Index: vte/ChangeLog =================================================================== RCS file: /cvs/gnome/vte/ChangeLog,v retrieving revision 1.524 diff -u -p -r1.524 ChangeLog --- vte/ChangeLog 2 May 2004 06:43:01 -0000 1.524 +++ vte/ChangeLog 6 May 2004 08:11:36 -0000 @@ -1,3 +1,22 @@ +2004-05-06 Padraig O'Briain + * src/vte.c, src/vteint.h: + Add new functions to support accessible text selection: + _vte_terminal_get_selection, _vte_terminal_get_start_selection, + _vte_terminal_get_end_selection, _vte_terminal_select_text, + _vte_terminal_remove_selection + * src/vteaccess.c: + (xy_from_offset): Fix for offset being entire text. + (vte_terminal_accessibility_selection_changed): VteTerminal's + selection-changed signal handler which emits text-selection-changed + signal. + (vte_terminal_accessible_initialize): Connect to VteTerminal's + selection-changed signal. + (vte_terminal_accessible_get_n_selections) Add implementation. + (vte_terminal_accessible_get_selection) Add implementation. + (vte_terminal_accessible_add_selection) Add implementation. + (vte_terminal_accessible_remove_selection) Add implementation. + (vte_terminal_accessible_set_selection) Add implementation. + 2004-05-02 nalin * src/reaper.c(vte_reaper_add_child): pass the global reaper in as data when adding the child source, not the terminal which called us. Index: vte/src/vte.c =================================================================== RCS file: /cvs/gnome/vte/src/vte.c,v retrieving revision 1.404 diff -u -p -r1.404 vte.c --- vte/src/vte.c 2 May 2004 06:43:01 -0000 1.404 +++ vte/src/vte.c 6 May 2004 08:11:37 -0000 @@ -15758,3 +15758,76 @@ _vte_terminal_accessible_ref(VteTerminal g_return_if_fail(VTE_IS_TERMINAL(terminal)); terminal->pvt->accessible_emit = TRUE; } + +char * +_vte_terminal_get_selection(VteTerminal *terminal) +{ + g_return_val_if_fail(VTE_IS_TERMINAL(terminal), NULL); + + return g_strdup (terminal->pvt->selection); +} + +void +_vte_terminal_get_start_selection(VteTerminal *terminal, long *x, long *y) +{ + struct selection_cell_coords ss; + + g_return_if_fail(VTE_IS_TERMINAL(terminal)); + + ss = terminal->pvt->selection_start; + + if (x) { + *x = ss.x; + } + + if (y) { + *y = ss.y; + } +} + +void +_vte_terminal_get_end_selection(VteTerminal *terminal, long *x, long *y) +{ + struct selection_cell_coords se; + + g_return_if_fail(VTE_IS_TERMINAL(terminal)); + + se = terminal->pvt->selection_end; + + if (x) { + *x = se.x; + } + + if (y) { + *y = se.y; + } +} + +void +_vte_terminal_select_text(VteTerminal *terminal, long start_x, long start_y, long end_x, long end_y, int start_offset, int end_offset) +{ + g_return_if_fail(VTE_IS_TERMINAL(terminal)); + + terminal->pvt->selection_type = selection_type_char; + terminal->pvt->has_selection = TRUE; + terminal->pvt->selecting_had_delta = TRUE; + terminal->pvt->selection_start.x = start_x; + terminal->pvt->selection_start.y = start_y; + terminal->pvt->selection_end.x = end_x; + terminal->pvt->selection_end.y = end_y; + vte_terminal_copy(terminal, + GDK_SELECTION_PRIMARY); + vte_invalidate_cells (terminal, + 0, + terminal->column_count, + MIN (start_y, end_y), + ABS (start_y - end_y) + 1); + + vte_terminal_emit_selection_changed(terminal); +} + +void +_vte_terminal_remove_selection(VteTerminal *terminal) +{ + vte_terminal_deselect_all (terminal); +} Index: vte/src/vteaccess.c =================================================================== RCS file: /cvs/gnome/vte/src/vteaccess.c,v retrieving revision 1.44 diff -u -p -r1.44 vteaccess.c --- vte/src/vteaccess.c 1 May 2004 07:12:51 -0000 1.44 +++ vte/src/vteaccess.c 6 May 2004 08:11:37 -0000 @@ -150,7 +150,7 @@ xy_from_offset (VteTerminalAccessiblePri } } if (i == priv->snapshot_linebreaks->len) { - if (offset < priv->snapshot_characters->len) { + if (offset <= priv->snapshot_characters->len) { cur_x = offset - cur_offset; cur_y = i - 1; } @@ -735,6 +735,16 @@ vte_terminal_accessible_visibility_notif } static void +vte_terminal_accessible_selection_changed (VteTerminal *terminal, + gpointer data) +{ + g_return_if_fail(VTE_IS_TERMINAL_ACCESSIBLE(data)); + g_return_if_fail(VTE_IS_TERMINAL(terminal)); + + g_signal_emit_by_name (data, "text_selection_changed"); +} + +static void vte_terminal_initialize (AtkObject *obj, gpointer data) { VteTerminal *terminal; @@ -777,6 +787,9 @@ vte_terminal_initialize (AtkObject *obj, g_signal_connect(G_OBJECT(terminal), "visibility-notify-event", GTK_SIGNAL_FUNC(vte_terminal_accessible_visibility_notify), obj); + g_signal_connect(G_OBJECT(terminal), "selection-changed", + GTK_SIGNAL_FUNC(vte_terminal_accessible_selection_changed), + obj); if (GTK_IS_WIDGET((GTK_WIDGET(terminal))->parent)) { parent = gtk_widget_get_accessible((GTK_WIDGET(terminal))->parent); @@ -1382,55 +1395,136 @@ vte_terminal_accessible_get_offset_at_po static gint vte_terminal_accessible_get_n_selections(AtkText *text) { - g_return_val_if_fail(VTE_IS_TERMINAL_ACCESSIBLE(text), 0); + GtkWidget *widget; + VteTerminal *terminal; + + g_return_val_if_fail(VTE_IS_TERMINAL_ACCESSIBLE(text), -1); vte_terminal_accessible_update_private_data_if_needed(ATK_OBJECT(text), NULL, NULL); - /* FIXME? */ - return 0; + + widget = GTK_ACCESSIBLE(text)->widget; + if (widget == NULL) { + /* State is defunct */ + return -1; + } + g_return_val_if_fail (VTE_IS_TERMINAL (widget), -1); + terminal = VTE_TERMINAL (widget); + return (vte_terminal_get_has_selection (terminal)) ? 1 : 0; } static gchar * vte_terminal_accessible_get_selection(AtkText *text, gint selection_number, gint *start_offset, gint *end_offset) { + GtkWidget *widget; + VteTerminal *terminal; + VteTerminalAccessiblePrivate *priv; + long start_x, start_y, end_x, end_y; + g_return_val_if_fail(VTE_IS_TERMINAL_ACCESSIBLE(text), NULL); vte_terminal_accessible_update_private_data_if_needed(ATK_OBJECT(text), NULL, NULL); - /* FIXME? */ - return NULL; + widget = GTK_ACCESSIBLE(text)->widget; + if (widget == NULL) { + /* State is defunct */ + return NULL; + } + g_return_val_if_fail (VTE_IS_TERMINAL (widget), NULL); + terminal = VTE_TERMINAL (widget); + if (!vte_terminal_get_has_selection (terminal)) { + return NULL; + } + if (selection_number != 0) { + return NULL; + } + + priv = g_object_get_data(G_OBJECT(text), + VTE_TERMINAL_ACCESSIBLE_PRIVATE_DATA); + _vte_terminal_get_start_selection (terminal, &start_x, &start_y); + *start_offset = offset_from_xy (priv, start_x, start_y); + _vte_terminal_get_end_selection (terminal, &end_x, &end_y); + *end_offset = offset_from_xy (priv, end_x, end_y); + return _vte_terminal_get_selection (terminal); } static gboolean vte_terminal_accessible_add_selection(AtkText *text, gint start_offset, gint end_offset) { + GtkWidget *widget; + VteTerminal *terminal; + VteTerminalAccessiblePrivate *priv; + gint start_x, start_y, end_x, end_y; + g_return_val_if_fail(VTE_IS_TERMINAL_ACCESSIBLE(text), FALSE); vte_terminal_accessible_update_private_data_if_needed(ATK_OBJECT(text), NULL, NULL); - /* FIXME? */ - return FALSE; + widget = GTK_ACCESSIBLE(text)->widget; + if (widget == NULL) { + /* State is defunct */ + return FALSE; + } + g_return_val_if_fail (VTE_IS_TERMINAL (widget), FALSE); + terminal = VTE_TERMINAL (widget); + g_return_val_if_fail (!vte_terminal_get_has_selection (terminal), FALSE); + priv = g_object_get_data(G_OBJECT(text), + VTE_TERMINAL_ACCESSIBLE_PRIVATE_DATA); + xy_from_offset (priv, start_offset, &start_x, &start_y); + xy_from_offset (priv, end_offset, &end_x, &end_y); + _vte_terminal_select_text (terminal, start_x, start_y, end_x, end_y, start_offset, end_offset); + return TRUE; } static gboolean vte_terminal_accessible_remove_selection(AtkText *text, gint selection_number) { + GtkWidget *widget; + VteTerminal *terminal; + g_return_val_if_fail(VTE_IS_TERMINAL_ACCESSIBLE(text), FALSE); vte_terminal_accessible_update_private_data_if_needed(ATK_OBJECT(text), NULL, NULL); - /* FIXME? */ - return FALSE; + widget = GTK_ACCESSIBLE(text)->widget; + if (widget == NULL) { + /* State is defunct */ + return FALSE; + } + g_return_val_if_fail (VTE_IS_TERMINAL (widget), FALSE); + terminal = VTE_TERMINAL (widget); + if (selection_number == 0 && vte_terminal_get_has_selection (terminal)) { + _vte_terminal_remove_selection (terminal); + return TRUE; + } else { + return FALSE; + } } static gboolean vte_terminal_accessible_set_selection(AtkText *text, gint selection_number, gint start_offset, gint end_offset) { + GtkWidget *widget; + VteTerminal *terminal; + g_return_val_if_fail(VTE_IS_TERMINAL_ACCESSIBLE(text), FALSE); vte_terminal_accessible_update_private_data_if_needed(ATK_OBJECT(text), NULL, NULL); - /* FIXME? */ - return FALSE; + widget = GTK_ACCESSIBLE(text)->widget; + if (widget == NULL) { + /* State is defunct */ + return FALSE; + } + g_return_val_if_fail (VTE_IS_TERMINAL (widget), FALSE); + terminal = VTE_TERMINAL (widget); + if (selection_number != 0) { + return FALSE; + } + if (vte_terminal_get_has_selection (terminal)) { + _vte_terminal_remove_selection (terminal); + } + + return vte_terminal_accessible_add_selection (text, start_offset, end_offset); } static gboolean @@ -1519,6 +1613,9 @@ vte_terminal_accessible_get_position(Atk *x = 0; *y = 0; widget = (GTK_ACCESSIBLE(component))->widget; + if (widget == NULL) { + return; + } if (!GTK_WIDGET_REALIZED(widget)) { return; } @@ -1543,6 +1640,9 @@ vte_terminal_accessible_get_size(AtkComp *width = 0; *height = 0; widget = (GTK_ACCESSIBLE(component))->widget; + if (widget == NULL) { + return; + } if (!GTK_WIDGET_REALIZED(widget)) { return; } @@ -1575,7 +1675,12 @@ vte_terminal_accessible_set_size(AtkComp { VteTerminal *terminal; gint columns, rows, xpad, ypad; - terminal = VTE_TERMINAL((GTK_ACCESSIBLE(component))->widget); + GtkWidget *widget; + widget = GTK_ACCESSIBLE(component)->widget; + if (widget == NULL) { + return FALSE; + } + terminal = VTE_TERMINAL(widget); vte_terminal_get_padding(terminal, &xpad, &ypad); /* If the size is an exact multiple of the cell size, use that, * otherwise round down. */ @@ -1599,6 +1704,9 @@ vte_terminal_accessible_grab_focus(AtkCo { GtkWidget *widget; widget = (GTK_ACCESSIBLE(component))->widget; + if (widget == NULL) { + return FALSE; + } if (GTK_WIDGET_HAS_FOCUS(widget)) { return TRUE; } Index: vte/src/vteint.h =================================================================== RCS file: /cvs/gnome/vte/src/vteint.h,v retrieving revision 1.1 diff -u -p -r1.1 vteint.h --- vte/src/vteint.h 16 Jun 2003 21:16:33 -0000 1.1 +++ vte/src/vteint.h 6 May 2004 08:11:37 -0000 @@ -26,6 +26,11 @@ G_BEGIN_DECLS void _vte_terminal_accessible_ref(VteTerminal *terminal); +char* _vte_terminal_get_selection(VteTerminal *terminal); +void _vte_terminal_get_start_selection(VteTerminal *terminal, long *x, long *y); +void _vte_terminal_get_end_selection(VteTerminal *terminal, long *x, long *y); +void _vte_terminal_select_text(VteTerminal *terminal, long start_x, long start_y, long end_x, long end_y, int start_offset, int end_offset); +void _vte_terminal_remove_selection(VteTerminal *terminal); G_END_DECLS