3 #define MAX_NAME_VALUE 20
8 #include <netinet/in.h>
9 #include <sys/socket.h>
54 /* GUI Information for the group */
59 GtkFrame *scroll_outer_frame;
82 GtkHBox *column1, *column2, *hbox;
102 /* Function prototypes */
106 static void _init_data(void);
107 static void _create_window(void);
108 static void _add_menu(GtkWidget ** menu, GtkWidget ** menuitem,
109 gchar * name, gboolean init_value, GCallback func);
110 static void _clear_tab(TabNumber tab_n);
111 static void _greyout_tab (GtkWidget *widget, gboolean is_sensitive);
112 static void _finished_group(TabNumber tab_n, gint group_num);
113 static gboolean _object_is_ours (AtkObject *aobject);
114 static void _create_event_watcher (void);
116 /* Mouse Watcher/Magnifier/Festival functions */
118 static gboolean _mouse_watcher (GSignalInvocationHint *ihint,
119 guint n_param_values,
120 const GValue *param_values,
122 static gboolean _button_watcher (GSignalInvocationHint *ihint,
123 guint n_param_values,
124 const GValue *param_values,
126 static void _send_to_magnifier (gint x, gint y, gint w, gint h);
127 static void _send_to_festival (const gchar * name,
128 const gchar * role_name, const gchar * accel);
129 static void _speak_caret_event (AtkObject * aobject);
130 static void _festival_say (const gchar * text);
131 static void _festival_write (const gchar * text, int fd);
132 static gint _festival_init (void);
134 /* Update functions */
136 static void _update_current_page(GtkNotebook *notebook, gpointer p,
138 static void _update(TabNumber top_tab, AtkObject *aobject);
140 /* Print functions */
142 static void _print_accessible (AtkObject *aobject);
144 static gint _print_object (AtkObject *aobject);
145 static gint _print_relation (AtkObject *aobject);
146 static gint _print_state (AtkObject *aobject);
148 static gint _print_action (AtkAction *aobject);
149 static gint _print_component (AtkComponent *aobject);
150 static gint _print_image (AtkImage *aobject);
151 static gint _print_selection (AtkSelection *aobject);
152 static gint _print_table (AtkTable *aobject);
153 static gint _print_text (AtkText *aobject);
154 static gint _print_text_attributes (AtkText *aobject);
155 static gint _print_value (AtkValue *aobject);
156 static void _print_value_type(gint group_num, gchar *type, GValue *value);
157 static gint _print_groupname(TabNumber tab_n, GroupId group_id,
158 const char *groupname);
159 static NameValue* _print_key_value(TabNumber tab_n, gint group_number,
160 const char *label, gpointer value, ValueType type);
161 static void _print_signal(AtkObject *aobject, FerretSignalType type,
162 const char *name, const char *info);
164 /* Data Access functions */
166 static GroupInfo* _get_group(TabInfo *tab, GroupId group_id,
167 const gchar *groupname);
168 void _get_group_scrolled(GroupInfo *group);
169 static NameValue* _get_name_value(GroupInfo *group, const gchar *label,
170 gpointer value, ValueType type);
172 /* Signal handlers */
174 static void _update_handlers(AtkObject *obj);
175 static void _notify_text_insert_handler (GObject *obj,
176 int position, int offset);
177 static void _notify_text_delete_handler (GObject *obj,
178 int position, int offset);
179 static void _notify_caret_handler (GObject *obj, int position);
180 static void _notify_table_row_inserted (GObject *obj,
181 gint start_offset, gint length);
182 static void _notify_table_column_inserted (GObject *obj,
183 gint start_offset, gint length);
184 static void _notify_table_row_deleted (GObject *obj,
185 gint start_offset, gint length);
186 static void _notify_table_column_deleted (GObject *obj,
187 gint start_offset, gint length);
188 static void _notify_table_row_reordered (GObject *obj);
189 static void _notify_table_column_reordered (GObject *obj);
190 static void _notify_object_child_added (GObject *obj,
191 gint index, AtkObject *child);
192 static void _notify_object_child_removed (GObject *obj,
193 gint index, AtkObject *child);
194 static void _notify_object_state_change (GObject *obj,
195 gchar *name, gboolean set);
197 /* Property handlers */
199 static void _property_change_handler (AtkObject *obj,
200 AtkPropertyValues *values);
202 /* Ferret GUI callbacks */
204 void _action_cb(GtkWidget *widget, gpointer *userdata);
205 void _toggle_terminal(GtkCheckMenuItem *checkmenuitem,
207 void _toggle_no_signals(GtkCheckMenuItem *checkmenuitem,
209 void _toggle_magnifier(GtkCheckMenuItem *checkmenuitem,
211 void _toggle_festival(GtkCheckMenuItem *checkmenuitem,
213 void _toggle_festival_terse(GtkCheckMenuItem *checkmenuitem,
215 void _toggle_trackmouse(GtkCheckMenuItem *checkmenuitem,
217 void _toggle_trackfocus(GtkCheckMenuItem *checkmenuitem,
220 /* Global variables */
221 static GtkNotebook *notebook;
222 static TabInfo *nbook_tabs[END_TABS];
223 static gint mouse_watcher_focus_id = -1;
224 static gint mouse_watcher_button_id = -1;
225 static gint focus_tracker_id = -1;
226 static gboolean use_magnifier = FALSE;
227 static gboolean use_festival = FALSE;
228 static gboolean track_mouse = FALSE;
229 static gboolean track_focus = TRUE;
230 static gboolean say_role = TRUE;
231 static gboolean say_accel = TRUE;
232 static gboolean display_ascii = FALSE;
233 static gboolean no_signals = FALSE;
234 static gint last_caret_offset = 0;
236 static AtkObject *last_object = NULL;
237 static GtkWidget *mainWindow = NULL;
238 static GtkWidget *vbox1 = NULL;
239 static GtkWidget *menu = NULL;
240 static GtkWidget *menutop = NULL;
241 static GtkWidget *menubar = NULL;
242 static GtkWidget *menuitem_terminal = NULL;
243 static GtkWidget *menuitem_no_signals = NULL;
244 static GtkWidget *menuitem_magnifier = NULL;
245 static GtkWidget *menuitem_festival = NULL;
246 static GtkWidget *menuitem_festival_terse = NULL;
247 static GtkWidget *menuitem_trackmouse = NULL;
248 static GtkWidget *menuitem_trackfocus = NULL;
250 #ifdef HAVE_SOCKADDR_UN_SUN_LEN
251 static struct sockaddr_un mag_server = { 0, AF_UNIX , "/tmp/magnifier_socket" };
252 static struct sockaddr_un client = { 0 , AF_UNIX, "/tmp/mag_client"};
254 static struct sockaddr_un mag_server = { AF_UNIX , "/tmp/magnifier_socket" };
255 static struct sockaddr_un client = { AF_UNIX, "/tmp/mag_client"};
258 /* GUI Information for the output window */
261 GtkWindow *outputWindow;
265 GtkWidget *textInsert;
270 _send_to_magnifier(gint x, gint y, gint w, gint h)
272 int desc, length_msg;
275 sprintf (buff, "~5:%d,%d", x+w/2, y+h/2);
278 g_print ("sending magnifier: %s\n", buff);
281 #ifdef HAVE_SOCKADDR_UN_SUN_LEN
282 mag_server.sun_len = SUN_LEN(&mag_server);
283 client.sun_len = SUN_LEN(&client);
286 if((desc=socket(AF_UNIX,SOCK_STREAM,0)) == -1){
290 unlink("/tmp/mag_client");
292 if (bind(desc, (struct sockaddr*)&client, sizeof(client)) == -1)
298 if (connect(desc,(struct sockaddr*)&mag_server,sizeof(mag_server)) == -1)
304 length_msg = write(desc,buff,strlen(buff));
305 unlink("/tmp/mag_client");
309 static int _festival_init (void)
312 struct sockaddr_in name;
315 name.sin_family = AF_INET;
316 name.sin_port = htons (1314);
317 name.sin_addr.s_addr = htonl(INADDR_ANY);
318 fd = socket (PF_INET, SOCK_STREAM, 0);
320 while (connect(fd, (struct sockaddr *) &name, sizeof (name)) < 0) {
327 _festival_write ("(audio_mode'async)", fd);
331 static void _festival_say (const gchar *text)
337 const gchar *stretch;
339 fprintf (stderr, "saying %s\n", text);
343 fd = _festival_init ();
346 quoted = g_malloc(100+strlen(text)*2);
348 stretch = g_strdup (g_getenv ("FESTIVAL_STRETCH"));
349 if (!stretch) stretch = "0.75";
350 sprintf (prefix, "(audio_mode'shutup)\n (Parameter.set 'Duration_Stretch %s)\n (SayText \"", stretch);
352 strcpy(quoted, prefix);
353 p = quoted + strlen (prefix);
355 if ( *text == '\\' || *text == '"' )
363 _festival_write (quoted, fd);
369 static void _send_to_festival (const gchar *role_name,
370 const gchar *name, const gchar *accel)
373 int len = (strlen (role_name)+1 + strlen (name)+2 + 4 + strlen (accel)+2);
378 string = (gchar *) g_malloc (len * sizeof (gchar));
387 if (ch == '_') ch = ' ';
396 if (ch == '_') ch = ' ';
399 if ((say_accel) && (strlen (accel) > 0))
401 accel_name = (gchar *)accel;
402 if (strncmp (accel, "<C", 2) == 0)
404 accel_name = strncpy (accel_name, " control ", 9);
406 else if (strncmp (accel, " control", 5))
415 while (accel_name[j])
417 ch = accel_name[j++];
418 if (ch == '_') ch = ' ';
424 _festival_say (string);
428 static void _festival_write (const gchar *command_string, int fd)
436 n_bytes = write(fd, command_string, strlen(command_string));
437 g_assert (n_bytes == strlen(command_string));
440 static void _speak_caret_event (AtkObject *aobject)
443 gint caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
446 if (abs(caret_offset - last_caret_offset) > 1)
448 text = atk_text_get_text_at_offset (ATK_TEXT (aobject),
450 ATK_TEXT_BOUNDARY_LINE_START,
456 text = atk_text_get_text_before_offset (ATK_TEXT (aobject),
458 ATK_TEXT_BOUNDARY_CHAR,
462 _festival_say (text);
464 last_caret_offset = caret_offset;
468 _greyout_tab (GtkWidget *page_child, gboolean is_sensitive)
472 tab = gtk_notebook_get_tab_label (notebook, page_child);
474 gtk_widget_set_sensitive (GTK_WIDGET (tab), is_sensitive);
478 _refresh_notebook (AtkObject *aobject)
480 if (ATK_IS_OBJECT (aobject))
482 _greyout_tab (nbook_tabs[ACTION]->page, ATK_IS_ACTION(aobject));
483 _greyout_tab (nbook_tabs[COMPONENT]->page, ATK_IS_COMPONENT(aobject));
484 _greyout_tab (nbook_tabs[IMAGE]->page, ATK_IS_IMAGE(aobject));
485 _greyout_tab (nbook_tabs[SELECTION]->page, ATK_IS_SELECTION(aobject));
486 _greyout_tab (nbook_tabs[TABLE]->page, ATK_IS_TABLE(aobject));
487 _greyout_tab (nbook_tabs[TEXT]->page, ATK_IS_TEXT(aobject));
488 _greyout_tab (nbook_tabs[VALUE]->page, ATK_IS_VALUE(aobject));
492 static void _print_accessible (AtkObject *aobject)
496 if (_object_is_ours(aobject))
499 g_print("\nFocus entered the ferret output window!\n");
503 _refresh_notebook(aobject);
506 g_print("\nFocus change\n");
508 /* Do not attach signal handlers if the user has asked not to */
510 _update_handlers(aobject);
512 last_object = aobject; /* _update_handler normally does this */
514 top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
515 _update(top_tab, aobject);
522 if (ATK_IS_TEXT (aobject))
527 len = atk_text_get_character_count (ATK_TEXT (aobject));
528 atk_text_get_character_extents (ATK_TEXT (aobject), 0,
533 atk_text_get_character_extents (ATK_TEXT (aobject), len-1,
538 w = MAX (x0+w0, xN+wN) - x;
539 h = MAX (y0+h0, yN+hN) - y;
547 else if (ATK_IS_COMPONENT (aobject))
549 atk_component_get_extents (ATK_COMPONENT(aobject),
553 if (w > -1) _send_to_magnifier (x, y, w, h);
558 _object_is_ours (AtkObject *aobject)
560 /* determine whether this object is parented by our own accessible... */
562 AtkObject *toplevel = aobject;
564 while (atk_object_get_role(aobject) != ATK_ROLE_FRAME)
566 aobject = atk_object_get_parent (aobject);
567 if (aobject == NULL) break;
572 * Some widgets do not have an ATK_ROLE_FRAME at the top,
579 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (toplevel));
580 if (widget == mainWindow)
588 ferret_get_name_from_container (AtkObject *aobject)
591 gint n = atk_object_get_n_accessible_children (aobject);
594 while (!s && (i < n))
597 child = atk_object_ref_accessible_child (aobject, i);
598 if (ATK_IS_TEXT (child))
600 gint count = atk_text_get_character_count (ATK_TEXT (child));
601 s = atk_text_get_text (ATK_TEXT (child),
605 g_object_unref (child);
617 _print_object (AtkObject *aobject)
620 G_CONST_RETURN gchar * parent_name = NULL;
621 G_CONST_RETURN gchar * name = NULL;
622 G_CONST_RETURN gchar * description = NULL;
623 G_CONST_RETURN gchar * typename = NULL;
624 G_CONST_RETURN gchar * parent_typename = NULL;
625 G_CONST_RETURN gchar * role_name = NULL;
626 G_CONST_RETURN gchar * accel_name = NULL;
627 G_CONST_RETURN gchar * text = NULL;
629 AtkObject *parent = NULL;
630 static AtkObject *prev_aobject = NULL;
632 gint index_in_parent = -1;
635 TabNumber tab_n = OBJECT;
637 group_num = _print_groupname(tab_n, OBJECT_INTERFACE, "Object Interface");
639 name = atk_object_get_name (aobject);
640 typename = g_type_name (G_OBJECT_TYPE (aobject));
641 description = atk_object_get_description (aobject);
642 parent = atk_object_get_parent(aobject);
644 index_in_parent = atk_object_get_index_in_parent(aobject);
645 n_children = atk_object_get_n_accessible_children(aobject);
646 role = atk_object_get_role(aobject);
647 role_name = atk_role_get_name(role);
649 if (ATK_IS_ACTION (aobject))
651 accel_name = atk_action_get_keybinding (ATK_ACTION(aobject), 0);
652 if (!accel_name) accel_name = "";
659 widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (aobject));
662 _print_key_value(tab_n, group_num, "Widget name",
663 (gpointer)gtk_widget_get_name (widget),
668 _print_key_value(tab_n, group_num, "Widget name", "No Widget",
674 _print_key_value(tab_n, group_num, "Accessible Type",
675 (gpointer)typename, VALUE_STRING);
679 _print_key_value(tab_n, group_num, "Accessible Type", "NULL",
685 _print_key_value(tab_n, group_num, "Accessible Name",
686 (gpointer)name, VALUE_STRING);
690 _print_key_value(tab_n, group_num, "Accessible Name", "(unknown)",
695 if (aobject != prev_aobject)
697 if (ATK_IS_TEXT (aobject) && !name)
700 atk_text_get_text_at_offset (ATK_TEXT (aobject),
702 ATK_TEXT_BOUNDARY_SENTENCE_END,
705 fprintf (stderr, "first sentence: %s\n", text);
706 _send_to_festival (role_name,
708 if (!name) name = "no name";
715 if (atk_object_get_role (aobject) == ATK_ROLE_TABLE_CELL)
717 gchar *cname = ferret_get_name_from_container (aobject);
718 if (cname) name = g_strdup (cname);
720 else if (atk_object_get_role (aobject) == ATK_ROLE_CHECK_BOX)
722 name = g_strdup ("check box");
729 _send_to_festival (role_name, name, accel_name);
736 parent_name = atk_object_get_name(parent);
738 parent_typename = g_type_name (G_OBJECT_TYPE (parent));
742 _print_key_value(tab_n, group_num, "Parent Accessible Type",
743 (gpointer)parent_typename, VALUE_STRING);
747 _print_key_value(tab_n, group_num,
748 "Parent Accessible Type", "NULL", VALUE_STRING);
753 _print_key_value(tab_n, group_num, "Parent Accessible Name",
754 (gpointer)parent_name, VALUE_STRING);
758 _print_key_value(tab_n, group_num,
759 "Parent Accessible Name", "NULL", VALUE_STRING);
762 output_str = g_strdup_printf("%d", index_in_parent);
763 _print_key_value(tab_n, group_num, "Index in Parent",
764 (gpointer)output_str, VALUE_STRING);
769 _print_key_value(tab_n, group_num, "Parent", "NULL", VALUE_STRING);
774 _print_key_value(tab_n, group_num, "Accessible Description",
775 (gpointer)description, VALUE_STRING);
779 _print_key_value(tab_n, group_num,
780 "Accessible Description", "NULL", VALUE_STRING);
785 _print_key_value(tab_n, group_num, "Accessible Role", (gpointer)role_name,
790 _print_key_value(tab_n, group_num, "Accessible Role", "NULL",
794 output_str = g_strdup_printf("%d", n_children);
795 _print_key_value(tab_n, group_num, "Number Children", (gpointer)output_str,
798 prev_aobject = aobject;
804 _print_relation (AtkObject *aobject)
806 AtkRelationSet* relation_set = atk_object_ref_relation_set (aobject);
807 gint n_relations = atk_relation_set_get_n_relations (relation_set);
809 TabNumber tab_n = OBJECT;
811 group_num = _print_groupname(tab_n, RELATION_INTERFACE,
812 "Relation Interface");
816 AtkRelation * relation;
817 G_CONST_RETURN gchar * relation_name = NULL;
818 G_CONST_RETURN gchar * relation_obj_name = NULL;
819 AtkRelationType relation_type;
820 AtkObject *relation_obj;
821 GPtrArray * relation_arry;
826 output_str = g_strdup_printf("%d", n_relations);
827 _print_key_value(tab_n, group_num,
828 "Number of Relations", (gpointer)output_str, VALUE_STRING);
831 for (i = 0; i < n_relations; i++)
833 relation = atk_relation_set_get_relation (relation_set, i);
835 relation_type = atk_relation_get_relation_type (relation);
836 relation_name = atk_relation_type_get_name (relation_type);
838 relation_arry = atk_relation_get_target(relation);
842 label_str = g_strdup_printf("Relation %d Name", i + 1);
843 _print_key_value(tab_n, group_num, label_str,
844 (gpointer)relation_name, VALUE_STRING);
849 label_str = g_strdup_printf("Relation %d Type", i + 1);
850 output_str = g_strdup_printf("%d", relation_type);
851 _print_key_value(tab_n, group_num, label_str,
852 (gpointer)output_str, VALUE_STRING);
857 label_str = g_strdup_printf("Relation %d with", i + 1);
858 output_str = g_strdup_printf("%d AtkObjects", relation_arry->len);
859 _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
864 for (j=0; j < relation_arry->len; j++)
866 label_str = g_strdup_printf(
867 "Relation %d,%d with AtkObject Name", i + 1, j + 1);
868 relation_obj = (AtkObject *)
869 g_ptr_array_index(relation_arry, j);
870 relation_obj_name = atk_object_get_name(relation_obj);
872 _print_key_value(tab_n, group_num, label_str,
873 (gpointer)relation_obj_name, VALUE_STRING);
878 g_object_unref (relation_set);
884 _print_state (AtkObject *aobject)
886 AtkStateSet *state_set = atk_object_ref_state_set(aobject);
888 TabNumber tab_n = OBJECT;
889 static AtkStateType states_to_track[] =
894 ATK_STATE_EXPANDABLE,
900 group_num = _print_groupname(tab_n, STATE_INTERFACE,
905 gboolean boolean_value;
906 AtkStateType one_state;
907 G_CONST_RETURN gchar *name;
910 for (i=0; i < sizeof(states_to_track)/sizeof(AtkStateType); i++)
912 one_state = (AtkStateType) states_to_track[i];
913 name = atk_state_type_get_name (one_state);
918 atk_state_set_contains_state (state_set, one_state);
919 _print_key_value(tab_n, group_num, name,
920 (gpointer)(&boolean_value), VALUE_BOOLEAN);
925 g_object_unref (state_set);
930 _print_action (AtkAction *aobject)
932 G_CONST_RETURN gchar *action_name;
933 G_CONST_RETURN gchar *action_description;
934 G_CONST_RETURN gchar *action_keybinding;
935 gchar *label_str, *output_str;
938 TabNumber tab_n = ACTION;
941 group_num = _print_groupname(tab_n, ACTION_INTERFACE,
944 num_actions = atk_action_get_n_actions (aobject);
945 output_str = g_strdup_printf("%d", num_actions);
946 _print_key_value(tab_n, group_num, "Number of Actions",
947 (gpointer) output_str, VALUE_STRING);
950 for (j = 0; j < num_actions; j++)
952 label_str = g_strdup_printf("Action %d Name", j + 1);
953 action_name = atk_action_get_name (aobject, j);
956 nv = _print_key_value(tab_n, group_num, label_str,
957 (gpointer) action_name, VALUE_BUTTON);
961 nv = _print_key_value(tab_n, group_num, label_str, "NULL",
965 nv->atkobj = ATK_OBJECT(aobject);
967 nv->signal_id = g_signal_connect (GTK_OBJECT (nv->button),
968 "clicked", G_CALLBACK (_action_cb), nv);
972 label_str = g_strdup_printf("Action %d Description", j + 1);
973 action_description = atk_action_get_description (aobject, j);
974 if (action_description)
976 _print_key_value(tab_n, group_num, label_str,
977 (gpointer)action_description, VALUE_STRING);
981 _print_key_value(tab_n, group_num, label_str, "NULL",
986 label_str = g_strdup_printf("Action %d Keybinding", j + 1);
987 action_keybinding = atk_action_get_keybinding (aobject, j);
988 if (action_keybinding)
990 _print_key_value(tab_n, group_num, label_str,
991 (gpointer)action_keybinding, VALUE_STRING);
995 _print_key_value(tab_n, group_num, label_str, "NULL",
1004 _print_component (AtkComponent *aobject)
1012 TabNumber tab_n = COMPONENT;
1014 group_num = _print_groupname(tab_n, COMPONENT_INTERFACE,
1015 "Component Interface");
1017 atk_component_get_extents (aobject,
1018 &x, &y, &width, &height, ATK_XY_SCREEN);
1020 output_str = g_strdup_printf("x: %d y: %d width: %d height %d",
1021 x, y, width, height);
1022 _print_key_value(tab_n, group_num, "Geometry", (gpointer)output_str,
1029 _print_image (AtkImage *aobject)
1031 G_CONST_RETURN gchar *image_desc;
1038 TabNumber tab_n = IMAGE;
1040 group_num = _print_groupname(tab_n, IMAGE_INTERFACE,
1043 image_desc = atk_image_get_image_description(aobject);
1046 _print_key_value(tab_n, group_num, "Description", (gpointer)image_desc,
1051 _print_key_value(tab_n, group_num, "Description", "NULL",
1055 atk_image_get_image_position(aobject, &x, &y, ATK_XY_SCREEN);
1056 atk_image_get_image_size(aobject, &height, &width);
1058 output_str = g_strdup_printf("x: %d y: %d width: %d height %d",
1059 x, y, width, height);
1060 _print_key_value(tab_n, group_num, "Geometry", (gpointer)output_str,
1067 _print_selection (AtkSelection *aobject)
1071 gchar *label_str, *output_str;
1073 gint n_selected, j, n_selectable;
1074 TabNumber tab_n = SELECTION;
1076 group_num = _print_groupname(tab_n, SELECTION_INTERFACE,
1077 "Selection Interface");
1079 n_selected = atk_selection_get_selection_count (aobject);
1080 output_str = g_strdup_printf ("%d", n_selected);
1081 _print_key_value (tab_n, group_num, "Number of Selected Children",
1082 (gpointer) output_str, VALUE_STRING);
1083 g_free (output_str);
1085 * The number of selected items is the number of children except for
1086 * a ComboBox where it is the number of items in the list.
1088 object = ATK_OBJECT (aobject);
1089 role = atk_object_get_role (object);
1090 if (role == ATK_ROLE_COMBO_BOX)
1092 object = atk_object_ref_accessible_child (object, 0);
1093 g_return_val_if_fail (atk_object_get_role (object) == ATK_ROLE_LIST,
1095 n_selectable = atk_object_get_n_accessible_children (object);
1096 g_object_unref (G_OBJECT (object));
1100 n_selectable = atk_object_get_n_accessible_children (object);
1102 output_str = g_strdup_printf ("%d", n_selectable);
1103 _print_key_value (tab_n, group_num, "Number of Selectable Children",
1104 (gpointer) output_str, VALUE_STRING);
1105 g_free (output_str);
1107 for (j = 0; j < n_selected; j++)
1109 G_CONST_RETURN gchar *selected_name;
1110 AtkObject *selected_object;
1112 selected_object = atk_selection_ref_selection (aobject, j);
1113 selected_name = atk_object_get_name (selected_object);
1114 if (selected_name == NULL)
1116 selected_name = "No name";
1118 label_str = g_strdup_printf ("Selected item: %d Name", j+1);
1119 _print_key_value (tab_n, group_num, label_str,
1120 (gpointer) selected_name, VALUE_STRING);
1122 g_object_unref (G_OBJECT (selected_object));
1128 _print_table (AtkTable *aobject)
1130 gchar *label_str, *output_str;
1131 G_CONST_RETURN gchar *col_desc;
1133 gint n_cols, n_rows;
1136 TabNumber tab_n = TABLE;
1138 group_num = _print_groupname(tab_n, TABLE_INTERFACE,
1141 n_cols = atk_table_get_n_columns(aobject);
1142 output_str = g_strdup_printf("%d", n_cols);
1143 _print_key_value(tab_n, group_num, "Number Columns", (gpointer)output_str,
1147 n_rows = atk_table_get_n_rows(aobject);
1148 output_str = g_strdup_printf("%d", n_rows);
1149 _print_key_value(tab_n, group_num, "Number Rows", (gpointer)output_str,
1153 caption = atk_table_get_caption(aobject);
1156 G_CONST_RETURN gchar* caption_name;
1158 caption_name = atk_object_get_name (caption);
1161 _print_key_value(tab_n, group_num, "Caption Name",
1162 (gpointer)caption_name, VALUE_STRING);
1166 for (i=0; i < n_cols; i++)
1168 label_str = g_strdup_printf("Column %d Description", i + 1);
1170 col_desc = atk_table_get_column_description(aobject, i);
1173 _print_key_value(tab_n, group_num, label_str, (gpointer)col_desc,
1178 _print_key_value(tab_n, group_num, label_str, "NULL",
1189 _print_text (AtkText *aobject)
1191 gchar *output_str, *text_val, *text_val_escaped;
1192 gint n_chars, caret_offset;
1193 gint start_offset, end_offset;
1196 TabNumber tab_n = TEXT;
1198 group_num = _print_groupname(tab_n, TEXT_INTERFACE,
1201 n_chars = atk_text_get_character_count(aobject);
1203 output_str = g_strdup_printf("%d", n_chars);
1204 _print_key_value(tab_n, group_num, "Total Character Count",
1205 (gpointer)output_str, VALUE_STRING);
1209 * Pass through g_strescape so that non-ASCII chars are made
1212 text_val = atk_text_get_text (aobject, 0, n_chars);
1215 text_val_escaped = g_strescape(text_val, NULL);
1216 _print_key_value (tab_n, group_num, "Text", (gpointer)text_val_escaped,
1219 g_free (text_val_escaped);
1223 _print_key_value (tab_n, group_num, "Text", "NULL", VALUE_TEXT);
1226 caret_offset = atk_text_get_caret_offset(aobject);
1227 output_str = g_strdup_printf("%d", caret_offset);
1228 _print_key_value(tab_n, group_num, "Caret Offset", (gpointer)output_str,
1232 if (caret_offset < 0)
1235 text_val = atk_text_get_text_at_offset (aobject, caret_offset,
1236 ATK_TEXT_BOUNDARY_CHAR,
1237 &start_offset, &end_offset);
1240 text_val_escaped = g_strescape(text_val, NULL);
1241 _print_key_value(tab_n, group_num, "Current Character",
1242 (gpointer)text_val_escaped, VALUE_STRING);
1244 g_free (text_val_escaped);
1248 _print_key_value(tab_n, group_num, "Current Character", "none",
1252 atk_text_get_character_extents (aobject, caret_offset,
1253 &x, &y, &w, &h, ATK_XY_SCREEN);
1254 output_str = g_strdup_printf ("(%d, %d) (%d, %d)", x, y, w, h);
1257 _print_key_value(tab_n, group_num, "Character Bounds (screen)",
1258 (gpointer)output_str, VALUE_STRING);
1262 atk_text_get_character_extents (aobject, caret_offset,
1263 &x, &y, &w, &h, ATK_XY_WINDOW);
1264 output_str = g_strdup_printf ("(%d, %d) (%d, %d)", x, y, w, h);
1267 _print_key_value(tab_n, group_num, "Character Bounds (window)",
1268 (gpointer)output_str, VALUE_STRING);
1272 text_val = atk_text_get_text_at_offset (aobject, caret_offset,
1273 ATK_TEXT_BOUNDARY_WORD_START,
1274 &start_offset, &end_offset);
1277 text_val_escaped = g_strescape(text_val, NULL);
1278 _print_key_value(tab_n, group_num, "Current Word",
1279 (gpointer)text_val_escaped, VALUE_STRING);
1281 g_free (text_val_escaped);
1285 _print_key_value(tab_n, group_num, "Current Word", "none",
1289 text_val = atk_text_get_text_at_offset (aobject, caret_offset,
1290 ATK_TEXT_BOUNDARY_LINE_START,
1291 &start_offset, &end_offset);
1294 text_val_escaped = g_strescape(text_val, NULL);
1295 _print_key_value(tab_n, group_num, "Current Line",
1296 (gpointer)text_val_escaped, VALUE_STRING);
1298 g_free (text_val_escaped);
1302 _print_key_value(tab_n, group_num, "Current Line", "none",
1306 text_val = atk_text_get_text_at_offset (aobject, caret_offset,
1307 ATK_TEXT_BOUNDARY_SENTENCE_START,
1308 &start_offset, &end_offset);
1311 text_val_escaped = g_strescape(text_val, NULL);
1312 _print_key_value(tab_n, group_num, "Current Sentence",
1313 (gpointer)text_val_escaped, VALUE_STRING);
1315 g_free (text_val_escaped);
1319 _print_key_value(tab_n, group_num, "Current Line", "none",
1326 _print_text_attributes (AtkText *aobject)
1328 AtkAttributeSet *attribute_set;
1329 AtkAttribute *attribute;
1330 gchar *output_str, *label_str;
1331 gint start_offset, end_offset, caret_offset;
1332 gint attribute_set_len, attribute_offset, i;
1335 TabNumber tab_n = TEXT;
1337 n_chars = atk_text_get_character_count(aobject);
1339 group_num = _print_groupname (tab_n, TEXT_ATTRIBUTES,
1340 "Text Attributes at Caret");
1342 caret_offset = atk_text_get_caret_offset(aobject);
1343 attribute_offset = caret_offset;
1348 attribute_set = atk_text_get_run_attributes(aobject, attribute_offset,
1349 &start_offset, &end_offset);
1351 label_str = g_strdup_printf("Attribute run start");
1353 output_str = g_strdup_printf("%d", start_offset);
1354 _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
1359 label_str = g_strdup_printf("Attribute run end");
1360 output_str = g_strdup_printf("%d", end_offset);
1361 _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
1366 if (attribute_set == NULL)
1367 attribute_set_len = 0;
1369 attribute_set_len = g_slist_length(attribute_set);
1371 label_str = g_strdup_printf("Number of Attributes");
1372 output_str = g_strdup_printf("%d", attribute_set_len);
1373 _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
1378 for (i=0; i < attribute_set_len; i++)
1380 attribute = ((AtkAttribute *) g_slist_nth(attribute_set, i)->data);
1382 _print_key_value(tab_n, group_num, attribute->name,
1383 (gpointer)attribute->value, VALUE_STRING);
1385 if (attribute_set != NULL)
1386 atk_attribute_set_free(attribute_set);
1393 _print_value (AtkValue *aobject)
1395 GValue *value_back, val;
1397 TabNumber tab_n = VALUE;
1401 group_num = _print_groupname(tab_n, VALUE_INTERFACE,
1404 atk_value_get_current_value(aobject, value_back);
1405 _print_value_type(group_num, "Value", value_back);
1406 atk_value_get_minimum_value(aobject, value_back);
1407 _print_value_type(group_num, "Minimum Value", value_back);
1408 atk_value_get_maximum_value(aobject, value_back);
1409 _print_value_type(group_num, "Maximum Value", value_back);
1414 _print_value_type(gint group_num, gchar *type, GValue *value)
1416 gchar *label_str = NULL;
1417 gchar *output_str = NULL;
1418 TabNumber tab_n = VALUE;
1420 if (G_VALUE_HOLDS_DOUBLE (value))
1422 label_str = g_strdup_printf("%s - Double", type);
1423 output_str = g_strdup_printf("%f",
1424 g_value_get_double (value));
1425 _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
1428 else if (G_VALUE_HOLDS_INT (value))
1430 label_str = g_strdup_printf("%s - Integer", type);
1431 output_str = g_strdup_printf("%d",
1432 g_value_get_int (value));
1433 _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
1438 _print_key_value(tab_n, group_num, "Value", "Unknown Type",
1449 _create_event_watcher (void)
1451 focus_tracker_id = atk_add_focus_tracker (_print_accessible);
1455 mouse_watcher_focus_id =
1456 atk_add_global_event_listener(_mouse_watcher,
1457 "Gtk:GtkWidget:enter_notify_event");
1458 mouse_watcher_button_id =
1459 atk_add_global_event_listener(_button_watcher,
1460 "Gtk:GtkWidget:button_press_event");
1465 _mouse_watcher (GSignalInvocationHint *ihint,
1466 guint n_param_values,
1467 const GValue *param_values,
1473 object = g_value_get_object (param_values + 0);
1475 if (GTK_IS_MENU(object)) return TRUE;
1477 g_assert (GTK_IS_WIDGET(object));
1479 widget = GTK_WIDGET (object);
1480 if (GTK_IS_WINDOW (widget))
1482 GtkWidget *focus_widget = GTK_WINDOW (widget)->focus_widget;
1483 if (focus_widget != NULL)
1484 widget = focus_widget;
1487 _print_accessible (gtk_widget_get_accessible (widget));
1492 _button_watcher (GSignalInvocationHint *ihint,
1493 guint n_param_values,
1494 const GValue *param_values,
1500 object = g_value_get_object (param_values + 0);
1502 widget = GTK_WIDGET (object);
1503 if (GTK_IS_CONTAINER (widget))
1505 if (G_VALUE_HOLDS_BOXED (param_values + 1))
1507 GdkEventButton *event;
1511 gint aobject_x, aobject_y;
1514 gp = g_value_get_boxed (param_values + 1);
1515 event = (GdkEventButton *) gp;
1516 aobject = gtk_widget_get_accessible (widget);
1517 aobject_x = aobject_y = 0;
1518 atk_component_get_position (ATK_COMPONENT (aobject),
1519 &aobject_x, &aobject_y,
1521 x = aobject_x + (gint) event->x;
1522 y = aobject_y + (gint) event->y;
1523 child = atk_component_ref_accessible_at_point (ATK_COMPONENT (aobject),
1529 _print_accessible (child);
1530 g_object_unref (child);
1534 if (!GTK_IS_MENU_ITEM (widget))
1536 g_print ("No child at position %d %d for %s\n",
1539 g_type_name (G_OBJECT_TYPE (widget)));
1548 static void _add_notebook_page (GtkNotebook *nbook,
1549 GtkWidget *content_widget,
1550 GtkWidget **new_page,
1551 const gchar *label_text)
1555 if (content_widget != NULL)
1557 *new_page = content_widget;
1561 *new_page = gtk_vpaned_new ();
1564 label = gtk_label_new ("");
1565 gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), label_text);
1566 gtk_notebook_append_page (notebook, *new_page, label);
1567 gtk_widget_show(*new_page);
1571 _create_notebook (void)
1574 notebook = GTK_NOTEBOOK (gtk_notebook_new());
1576 tab = nbook_tabs[OBJECT];
1577 _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Object</b>");
1579 tab = nbook_tabs[ACTION];
1580 _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Action</b>");
1582 tab = nbook_tabs[COMPONENT];
1583 _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Component</b>");
1585 tab = nbook_tabs[IMAGE];
1586 _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Image</b>");
1588 tab = nbook_tabs[SELECTION];
1589 _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Selection</b>");
1591 tab = nbook_tabs[TABLE];
1592 _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Table</b>");
1594 tab = nbook_tabs[TEXT];
1595 _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>Te_xt</b>");
1597 tab = nbook_tabs[VALUE];
1598 _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Value</b>");
1600 g_signal_connect (GTK_OBJECT (notebook),
1602 G_CALLBACK (_update_current_page),
1611 the_tab = g_new0(TabInfo, 1);
1612 the_tab->page = NULL;
1613 the_tab->main_box = gtk_vbox_new(FALSE, 20);
1614 the_tab->name = "Object";
1615 nbook_tabs[OBJECT] = the_tab;
1617 the_tab = g_new0(TabInfo, 1);
1618 the_tab->page = NULL;
1619 the_tab->main_box = gtk_vbox_new(FALSE, 20);
1620 the_tab->name = "Action";
1621 nbook_tabs[ACTION] = the_tab;
1623 the_tab = g_new0(TabInfo, 1);
1624 the_tab->page = NULL;
1625 the_tab->main_box = gtk_vbox_new(FALSE, 20);
1626 the_tab->name = "Component";
1627 nbook_tabs[COMPONENT] = the_tab;
1629 the_tab = g_new0(TabInfo, 1);
1630 the_tab->page = NULL;
1631 the_tab->main_box = gtk_vbox_new(FALSE, 20);
1632 the_tab->name = "Image";
1633 nbook_tabs[IMAGE] = the_tab;
1635 the_tab = g_new0(TabInfo, 1);
1636 the_tab->page = NULL;
1637 the_tab->main_box = gtk_vbox_new(FALSE, 20);
1638 the_tab->name = "Selection";
1639 nbook_tabs[SELECTION] = the_tab;
1641 the_tab = g_new0(TabInfo, 1);
1642 the_tab->page = NULL;
1643 the_tab->main_box = gtk_vbox_new(FALSE, 20);
1644 the_tab->name = "Table";
1645 nbook_tabs[TABLE] = the_tab;
1647 the_tab = g_new0(TabInfo, 1);
1648 the_tab->page = NULL;
1649 the_tab->main_box = gtk_vbox_new(FALSE, 20);
1650 the_tab->name = "Text";
1651 nbook_tabs[TEXT] = the_tab;
1653 the_tab = g_new0(TabInfo, 1);
1654 the_tab->page = NULL;
1655 the_tab->main_box = gtk_vbox_new(FALSE, 20);
1656 the_tab->name = "Value";
1657 nbook_tabs[VALUE] = the_tab;
1661 _create_window (void)
1663 static GtkWidget *window = NULL;
1667 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1668 gtk_widget_set_name (window, "Ferret Window");
1670 g_signal_connect (GTK_OBJECT (window), "destroy",
1671 G_CALLBACK (gtk_widget_destroyed),
1674 gtk_window_set_title (GTK_WINDOW (window), "GTK+ Ferret Output");
1675 gtk_window_set_default_size (GTK_WINDOW (window), 333, 550);
1676 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1678 vbox1 = gtk_vbox_new (FALSE, 0);
1679 gtk_container_add (GTK_CONTAINER (window), vbox1);
1680 gtk_widget_show (vbox1);
1682 menubar = gtk_menu_bar_new ();
1683 gtk_box_pack_start (GTK_BOX (vbox1), menubar, FALSE, TRUE, 0);
1684 gtk_widget_show (menubar);
1685 menutop = gtk_menu_item_new_with_label("Menu");
1686 gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menutop);
1687 gtk_widget_show (menutop);
1688 menu = gtk_menu_new();
1689 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menutop), menu);
1690 gtk_widget_show (menu);
1692 _add_menu(&menu, &menuitem_trackmouse, "Track Mouse", track_mouse,
1693 G_CALLBACK(_toggle_trackmouse));
1694 _add_menu(&menu, &menuitem_trackfocus, "Track Focus", track_focus,
1695 G_CALLBACK(_toggle_trackfocus));
1696 _add_menu(&menu, &menuitem_magnifier, "Magnifier", use_magnifier,
1697 G_CALLBACK(_toggle_magnifier));
1698 _add_menu(&menu, &menuitem_festival, "Festival", use_festival,
1699 G_CALLBACK(_toggle_festival));
1700 _add_menu(&menu, &menuitem_festival_terse, "Festival Terse",
1701 (!say_role && !say_accel),
1702 G_CALLBACK(_toggle_festival_terse));
1703 _add_menu(&menu, &menuitem_terminal, "Terminal Output", display_ascii,
1704 G_CALLBACK(_toggle_terminal));
1705 _add_menu(&menu, &menuitem_no_signals, "No ATK Signals", no_signals,
1706 G_CALLBACK(_toggle_no_signals));
1708 _create_notebook ();
1709 gtk_container_add (GTK_CONTAINER (vbox1), GTK_WIDGET (notebook));
1710 gtk_widget_show (GTK_WIDGET (notebook));
1712 if (!gtk_widget_get_visible (window))
1713 gtk_widget_show (window);
1715 mainWindow = GTK_WIDGET (window);
1719 _add_menu(GtkWidget ** menu, GtkWidget ** menuitem, gchar * name,
1720 gboolean init_value, GCallback func)
1722 *menuitem = gtk_check_menu_item_new_with_label(name);
1723 gtk_check_menu_item_set_active(
1724 GTK_CHECK_MENU_ITEM(*menuitem), init_value);
1725 gtk_menu_shell_append (GTK_MENU_SHELL (*menu), *menuitem);
1726 gtk_widget_show(*menuitem);
1727 g_signal_connect(GTK_OBJECT(*menuitem), "toggled", func, NULL);
1731 gtk_module_init(gint argc, char* argv[])
1733 if (g_getenv ("FERRET_ASCII"))
1734 display_ascii = TRUE;
1736 if (g_getenv ("FERRET_NOSIGNALS"))
1740 g_print("GTK ferret Module loaded\n");
1742 if (g_getenv("FERRET_MAGNIFIER"))
1743 use_magnifier = TRUE;
1745 if (g_getenv ("FERRET_FESTIVAL"))
1746 use_festival = TRUE;
1748 if (g_getenv ("FERRET_MOUSETRACK"))
1751 if (g_getenv ("FERRET_TERSE"))
1761 _create_event_watcher();
1767 _clear_tab(TabNumber tab_n)
1769 GList *group_list, *nv_list;
1774 tab = nbook_tabs[tab_n];
1776 for (group_list = tab->groups; group_list; group_list = group_list->next)
1778 group = (GroupInfo *) group_list->data;
1780 if (group->is_scrolled)
1781 gtk_widget_hide(GTK_WIDGET(group->scroll_outer_frame));
1783 gtk_widget_hide(GTK_WIDGET(group->frame));
1784 gtk_widget_hide(GTK_WIDGET(group->group_vbox));
1786 for (nv_list = group->name_value; nv_list; nv_list = nv_list->next)
1788 nv = (NameValue *) nv_list->data;
1790 gtk_widget_hide(GTK_WIDGET(nv->column1));
1791 gtk_widget_hide(GTK_WIDGET(nv->column2));
1792 gtk_widget_hide(GTK_WIDGET(nv->label));
1797 gtk_widget_hide(GTK_WIDGET(nv->string));
1800 gtk_widget_hide(GTK_WIDGET(nv->boolean));
1803 gtk_widget_hide(GTK_WIDGET(nv->text));
1806 gtk_widget_hide(GTK_WIDGET(nv->button));
1809 gtk_widget_hide(GTK_WIDGET(nv->hbox));
1811 /* Disconnect signal handler if any */
1812 if (nv->signal_id != -1)
1813 g_signal_handler_disconnect(nv->button, nv->signal_id);
1821 _print_groupname(TabNumber tab_n, GroupId group_id,
1822 const char *groupname)
1825 GroupInfo *the_group;
1829 g_print("\n<%s>\n", groupname);
1831 tab = nbook_tabs[tab_n];
1832 the_group = _get_group(tab, group_id, groupname);
1833 rc = g_list_index(tab->groups, the_group);
1838 _get_group(TabInfo *tab, GroupId group_id, const gchar *groupname)
1840 GroupInfo *group = NULL;
1841 gboolean found = FALSE;
1844 for (group_list = tab->groups; group_list; group_list = group_list->next)
1846 group = (GroupInfo *) group_list->data;
1847 if (group_id == group->group_id)
1856 /* build a new one */
1857 group = (GroupInfo *)g_new0(GroupInfo, 1);
1858 group->group_id = group_id;
1859 _get_group_scrolled(group);
1861 if (group->is_scrolled)
1863 group->frame = gtk_scrolled_window_new (NULL, NULL);
1864 gtk_widget_set_size_request (GTK_WIDGET (group->frame), -2,
1865 group->default_height);
1866 group->scroll_outer_frame = GTK_FRAME(gtk_frame_new(groupname));
1867 gtk_container_add(GTK_CONTAINER(group->scroll_outer_frame),
1872 group->frame = gtk_frame_new(groupname);
1875 gtk_container_set_border_width(GTK_CONTAINER(group->frame), 10);
1877 group->name = g_strdup(groupname);
1878 group->group_vbox = GTK_VBOX(gtk_vbox_new(FALSE, 10));
1880 if (group->is_scrolled)
1882 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (group->frame),
1883 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1884 gtk_scrolled_window_add_with_viewport(
1885 GTK_SCROLLED_WINDOW(group->frame),
1886 GTK_WIDGET(group->group_vbox));
1890 gtk_container_add(GTK_CONTAINER(group->frame),
1891 GTK_WIDGET(group->group_vbox));
1894 tab->groups = g_list_append (tab->groups, group);
1896 if (group->is_scrolled)
1898 gtk_box_pack_start (GTK_BOX (tab->main_box),
1899 GTK_WIDGET (group->scroll_outer_frame),
1904 gtk_box_pack_start (GTK_BOX (tab->main_box),
1905 GTK_WIDGET (group->frame),
1914 _get_group_scrolled(GroupInfo *group)
1916 if (group->group_id == OBJECT_INTERFACE)
1918 group->is_scrolled = FALSE;
1920 else if (group->group_id == RELATION_INTERFACE)
1922 group->is_scrolled = TRUE;
1923 group->default_height = 50;
1925 else if (group->group_id == STATE_INTERFACE)
1927 group->is_scrolled = TRUE;
1928 group->default_height = 100;
1930 else if (group->group_id == ACTION_INTERFACE)
1932 group->is_scrolled = TRUE;
1933 group->default_height = 200;
1935 else if (group->group_id == TEXT_ATTRIBUTES)
1937 group->is_scrolled = TRUE;
1938 group->default_height = 70;
1942 group->is_scrolled = FALSE;
1947 _get_name_value(GroupInfo *group, const gchar *label,
1948 gpointer value_ptr, ValueType type)
1950 NameValue *name_value = NULL;
1953 gboolean found = FALSE;
1954 static char *empty_string = "";
1958 label = empty_string;
1961 for (nv_list = group->name_value; nv_list; nv_list = nv_list->next)
1963 name_value = (NameValue *) nv_list->data;
1964 if (!name_value->active)
1973 name_value = (NameValue *)g_new0(NameValue, 1);
1974 name_value->column1 = GTK_HBOX(gtk_hbox_new(FALSE, 10));
1975 name_value->column2 = GTK_HBOX(gtk_hbox_new(FALSE, 10));
1976 name_value->hbox = GTK_HBOX(gtk_hbox_new(FALSE, 5));
1977 name_value->label = GTK_LABEL(gtk_label_new(label));
1978 name_value->string = gtk_label_new (NULL);
1979 name_value->boolean = gtk_check_button_new ();
1980 gtk_entry_buffer_set_max_length (gtk_entry_get_buffer (GTK_ENTRY (name_value->text)), 1000);
1981 name_value->button = GTK_BUTTON(gtk_button_new ());
1983 gtk_box_pack_end(GTK_BOX(name_value->column1),
1984 GTK_WIDGET(name_value->label), FALSE, FALSE, 10);
1989 gtk_label_set_text(GTK_LABEL(name_value->string),
1990 (gchar *) value_ptr);
1991 gtk_box_pack_start(GTK_BOX(name_value->column2),
1992 GTK_WIDGET(name_value->string), FALSE, FALSE, 10);
1995 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(name_value->boolean),
1996 *((gboolean *)value_ptr));
1997 gtk_widget_set_sensitive(name_value->boolean, FALSE);
1998 gtk_box_pack_start(GTK_BOX(name_value->column2),
1999 GTK_WIDGET(name_value->boolean), FALSE, FALSE, 10);
2002 gtk_entry_set_text (GTK_ENTRY (name_value->text),
2003 (gchar *)value_ptr);
2004 gtk_box_pack_start(GTK_BOX(name_value->column2),
2005 GTK_WIDGET(name_value->text), FALSE, FALSE, 10);
2007 value = &(name_value->button_gval);
2008 memset (value, 0, sizeof (GValue));
2009 g_value_init (value, G_TYPE_STRING);
2010 g_value_set_string (value, (gchar *)value_ptr);
2011 g_object_set_property(G_OBJECT(name_value->button),
2013 gtk_box_pack_start(GTK_BOX(name_value->column2),
2014 GTK_WIDGET(name_value->button), FALSE, FALSE, 10);
2018 gtk_box_pack_start (GTK_BOX (name_value->hbox),
2019 GTK_WIDGET (name_value->column1),
2021 gtk_box_pack_start (GTK_BOX (name_value->hbox),
2022 GTK_WIDGET (name_value->column2),
2024 gtk_container_add(GTK_CONTAINER(group->group_vbox),
2025 GTK_WIDGET(name_value->hbox));
2026 group->name_value = g_list_append (group->name_value, name_value);
2030 gtk_label_set_text(GTK_LABEL(name_value->label), label);
2034 gtk_label_set_text(GTK_LABEL(name_value->string),
2035 (gchar *) value_ptr);
2038 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(name_value->boolean),
2039 *((gboolean *)value_ptr));
2040 gtk_widget_set_sensitive(name_value->boolean, FALSE);
2043 gtk_entry_set_text (GTK_ENTRY (name_value->text),
2044 (gchar *) value_ptr);
2047 value = &(name_value->button_gval);
2048 memset (value, 0, sizeof (GValue));
2049 g_value_init (value, G_TYPE_STRING);
2050 g_value_set_string (value, (gchar *)value_ptr);
2051 g_object_set_property(G_OBJECT(name_value->button),
2057 name_value->active = TRUE;
2058 name_value->type = type;
2059 name_value->signal_id = -1;
2061 gtk_widget_show(GTK_WIDGET(name_value->label));
2066 gtk_widget_show(GTK_WIDGET(name_value->string));
2069 gtk_widget_show(GTK_WIDGET(name_value->boolean));
2072 gtk_widget_show(GTK_WIDGET(name_value->text));
2075 gtk_widget_show(GTK_WIDGET(name_value->button));
2079 gtk_widget_show(GTK_WIDGET(name_value->column1));
2080 gtk_widget_show(GTK_WIDGET(name_value->column2));
2081 gtk_widget_show(GTK_WIDGET(name_value->hbox));
2082 gtk_widget_show(GTK_WIDGET(group->group_vbox));
2088 _print_key_value(TabNumber tab_n, gint group_number,
2089 const char *label, gpointer value, ValueType type)
2092 GroupInfo *the_group;
2096 if (type == VALUE_BOOLEAN)
2098 if (*((gboolean *)value))
2099 g_print("\t%-30s\tTRUE\n", label);
2101 g_print("\t%-30s\tFALSE\n", label);
2105 g_print("\t%-30s\t%s\n", label,
2106 value ? (gchar *)value : "NULL");
2110 tab = nbook_tabs[tab_n];
2111 the_group = (GroupInfo *)g_list_nth_data(tab->groups, group_number);
2112 return _get_name_value(the_group, label, (gpointer)value, type);
2116 _finished_group(TabNumber tab_no, gint group_number)
2119 GroupInfo *the_group;
2121 tab = nbook_tabs[tab_no];
2123 the_group = (GroupInfo *)g_list_nth_data(tab->groups, group_number);
2125 if (the_group->is_scrolled)
2126 gtk_widget_show(GTK_WIDGET(the_group->scroll_outer_frame));
2128 gtk_widget_show(GTK_WIDGET(the_group->frame));
2129 gtk_widget_show(GTK_WIDGET(the_group->group_vbox));
2130 gtk_widget_show(GTK_WIDGET(tab->main_box));
2133 /* Signal handlers */
2135 static gulong child_added_id = 0;
2136 static gulong child_removed_id = 0;
2137 static gulong state_change_id = 0;
2139 static gulong text_caret_handler_id = 0;
2140 static gulong text_inserted_id = 0;
2141 static gulong text_deleted_id = 0;
2143 static gulong table_row_inserted_id = 0;
2144 static gulong table_column_inserted_id = 0;
2145 static gulong table_row_deleted_id = 0;
2146 static gulong table_column_deleted_id = 0;
2147 static gulong table_row_reordered_id = 0;
2148 static gulong table_column_reordered_id = 0;
2150 static gulong property_id = 0;
2153 _update_handlers(AtkObject *obj)
2155 /* Remove signal handlers from object that had focus before */
2157 if (last_object != NULL && G_TYPE_CHECK_INSTANCE(last_object))
2159 if (child_added_id != 0)
2160 g_signal_handler_disconnect(last_object, child_added_id);
2161 if (child_removed_id != 0)
2162 g_signal_handler_disconnect(last_object, child_removed_id);
2163 if (state_change_id != 0)
2164 g_signal_handler_disconnect(last_object, state_change_id);
2166 if (text_caret_handler_id != 0)
2167 g_signal_handler_disconnect(last_object, text_caret_handler_id);
2168 if (text_inserted_id != 0)
2169 g_signal_handler_disconnect(last_object, text_inserted_id);
2170 if (text_deleted_id != 0)
2171 g_signal_handler_disconnect(last_object, text_deleted_id);
2173 if (table_row_inserted_id != 0)
2174 g_signal_handler_disconnect(last_object, table_row_inserted_id);
2175 if (table_column_inserted_id != 0)
2176 g_signal_handler_disconnect(last_object, table_column_inserted_id);
2177 if (table_row_deleted_id != 0)
2178 g_signal_handler_disconnect(last_object, table_row_deleted_id);
2179 if (table_column_deleted_id != 0)
2180 g_signal_handler_disconnect(last_object, table_column_deleted_id);
2181 if (table_row_reordered_id != 0)
2182 g_signal_handler_disconnect(last_object, table_row_reordered_id);
2183 if (table_column_reordered_id != 0)
2184 g_signal_handler_disconnect(last_object, table_column_reordered_id);
2185 if (property_id != 0)
2186 g_signal_handler_disconnect(last_object, property_id);
2188 g_object_unref(last_object);
2194 child_removed_id = 0;
2195 text_caret_handler_id = 0;
2196 text_inserted_id = 0;
2197 text_deleted_id = 0;
2198 table_row_inserted_id = 0;
2199 table_column_inserted_id = 0;
2200 table_row_deleted_id = 0;
2201 table_column_deleted_id = 0;
2202 table_row_reordered_id = 0;
2203 table_column_reordered_id = 0;
2206 if (!G_TYPE_CHECK_INSTANCE(obj))
2212 /* Add signal handlers to object that now has focus. */
2214 if (ATK_IS_OBJECT(obj))
2216 child_added_id = g_signal_connect_closure (obj,
2217 "children_changed::add",
2218 g_cclosure_new (G_CALLBACK (_notify_object_child_added),
2219 NULL, NULL), FALSE);
2221 child_removed_id = g_signal_connect_closure (obj,
2222 "children_changed::remove",
2223 g_cclosure_new (G_CALLBACK (_notify_object_child_removed),
2224 NULL, NULL), FALSE);
2226 state_change_id = g_signal_connect_closure (obj,
2228 g_cclosure_new (G_CALLBACK (_notify_object_state_change),
2229 NULL, NULL), FALSE);
2232 if (ATK_IS_TEXT(obj))
2234 text_caret_handler_id = g_signal_connect_closure_by_id (obj,
2235 g_signal_lookup ("text_caret_moved", G_OBJECT_TYPE (obj)),
2236 0, g_cclosure_new (G_CALLBACK (_notify_caret_handler),
2237 NULL, NULL), FALSE);
2238 text_inserted_id = g_signal_connect_closure (obj,
2239 "text_changed::insert",
2240 g_cclosure_new (G_CALLBACK (_notify_text_insert_handler),
2241 NULL, NULL), FALSE);
2242 text_deleted_id = g_signal_connect_closure (obj,
2243 "text_changed::delete",
2244 g_cclosure_new (G_CALLBACK (_notify_text_delete_handler),
2245 NULL, NULL), FALSE);
2248 if (ATK_IS_TABLE(obj))
2250 table_row_inserted_id = g_signal_connect_closure_by_id (obj,
2251 g_signal_lookup ("row_inserted", G_OBJECT_TYPE (obj)),
2252 0, g_cclosure_new (G_CALLBACK (_notify_table_row_inserted),
2253 NULL, NULL), FALSE);
2254 table_column_inserted_id = g_signal_connect_closure_by_id (obj,
2255 g_signal_lookup ("column_inserted", G_OBJECT_TYPE (obj)),
2256 0, g_cclosure_new (G_CALLBACK (_notify_table_column_inserted),
2257 NULL, NULL), FALSE);
2258 table_row_deleted_id = g_signal_connect_closure_by_id (obj,
2259 g_signal_lookup ("row_deleted", G_OBJECT_TYPE (obj)),
2260 0, g_cclosure_new (G_CALLBACK (_notify_table_row_deleted),
2261 NULL, NULL), FALSE);
2262 table_column_deleted_id = g_signal_connect_closure_by_id (obj,
2263 g_signal_lookup ("column_deleted", G_OBJECT_TYPE (obj)),
2264 0, g_cclosure_new (G_CALLBACK (_notify_table_column_deleted),
2265 NULL, NULL), FALSE);
2266 table_row_reordered_id = g_signal_connect_closure_by_id (obj,
2267 g_signal_lookup ("row_reordered", G_OBJECT_TYPE (obj)),
2268 0, g_cclosure_new (G_CALLBACK (_notify_table_row_reordered),
2269 NULL, NULL), FALSE);
2270 table_column_reordered_id = g_signal_connect_closure_by_id (obj,
2271 g_signal_lookup ("column_reordered", G_OBJECT_TYPE (obj)),
2272 0, g_cclosure_new (G_CALLBACK (_notify_table_column_reordered),
2273 NULL, NULL), FALSE);
2276 property_id = g_signal_connect_closure_by_id (obj,
2277 g_signal_lookup ("property_change", G_OBJECT_TYPE (obj)),
2278 0, g_cclosure_new (G_CALLBACK (_property_change_handler),
2286 _notify_text_insert_handler (GObject *obj, int position, int offset)
2288 gchar *text = atk_text_get_text (ATK_TEXT (obj), position, position + offset);
2289 gchar *output_str = g_strdup_printf("position %d, length %d text: %s",
2290 position, offset, text ? text: "<NULL>");
2291 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
2292 "Text Insert", output_str);
2297 _notify_text_delete_handler (GObject *obj, int position, int offset)
2299 gchar *text = atk_text_get_text (ATK_TEXT (obj), position, position + offset);
2300 gchar *output_str = g_strdup_printf("position %d, length %d text: %s",
2301 position, offset, text ? text: "<NULL>");
2302 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
2303 "Text Delete", output_str);
2308 _notify_caret_handler (GObject *obj, int position)
2310 gchar *output_str = g_strdup_printf("position %d", position);
2311 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
2312 "Text Caret Moved", output_str);
2319 _notify_table_row_inserted (GObject *obj, gint start_offset,
2323 g_strdup_printf("position %d, num of rows inserted %d!\n",
2324 start_offset, length);
2325 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2326 "Table Row Inserted", output_str);
2331 _notify_table_column_inserted (GObject *obj, gint start_offset,
2335 g_strdup_printf("position %d, num of rows inserted %d!\n",
2336 start_offset, length);
2337 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2338 "Table Column Inserted", output_str);
2343 _notify_table_row_deleted (GObject *obj, gint start_offset,
2346 gchar *output_str = g_strdup_printf("position %d, num of rows inserted %d!\n",
2347 start_offset, length);
2348 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2349 "Table Row Deleted", output_str);
2354 _notify_table_column_deleted (GObject *obj, gint start_offset,
2357 gchar *output_str = g_strdup_printf("position %d, num of rows inserted %d!\n",
2358 start_offset, length);
2359 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2360 "Table Column Deleted", output_str);
2365 _notify_table_row_reordered (GObject *obj)
2367 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2368 "Table Row Reordered", NULL);
2372 _notify_table_column_reordered (GObject *obj)
2374 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2375 "Table Column Reordered", NULL);
2378 /* Object signals */
2381 _notify_object_child_added (GObject *obj, gint index,
2384 gchar *output_str = g_strdup_printf("index %d", index);
2385 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
2386 "Child Added", output_str);
2391 _notify_object_child_removed (GObject *obj, gint index,
2394 gchar *output_str = g_strdup_printf("index %d", index);
2395 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
2396 "Child Removed", output_str);
2401 _notify_object_state_change (GObject *obj, gchar *name, gboolean set)
2403 gchar *output_str = g_strdup_printf("name %s %s set",
2404 name, set ? "is" : "was");
2405 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
2406 "State Change", output_str);
2411 /* Function to print signals */
2414 _print_signal(AtkObject *aobject, FerretSignalType type,
2415 const char *name, const char *info)
2417 TabNumber top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
2425 g_print("SIGNAL:\t%-34s\t%s\n", name, info);
2427 g_print("SIGNAL:\t%-34s\n", name);
2432 if ((type == FERRET_SIGNAL_TEXT) && (!strncmp(name, "Text Caret", 10)))
2434 _speak_caret_event (aobject);
2436 else if (type == FERRET_SIGNAL_TEXT)
2438 last_caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
2442 if (use_magnifier && ATK_IS_TEXT (aobject) &&
2443 (type == FERRET_SIGNAL_TEXT) && (!strncmp(name, "Text Caret", 10)))
2446 gint caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
2447 atk_text_get_character_extents ( ATK_TEXT (aobject), caret_offset, &x, &y, &w, &h, ATK_XY_SCREEN);
2448 _send_to_magnifier (x, y, w, h);
2451 if ((type == FERRET_SIGNAL_TEXT && top_tab == TEXT) ||
2452 (type == FERRET_SIGNAL_TABLE && top_tab == TABLE) ||
2453 (type == FERRET_SIGNAL_OBJECT && top_tab == OBJECT))
2456 g_print("Updating tab\n");
2458 _update(top_tab, aobject);
2462 /* Update functions */
2465 _update (TabNumber top_tab, AtkObject *aobject)
2469 if (top_tab >= OBJECT && top_tab < END_TABS)
2471 _clear_tab(top_tab);
2474 if (top_tab == OBJECT && ATK_IS_OBJECT(aobject))
2476 group_num = _print_object(aobject);
2477 _finished_group(OBJECT, group_num);
2478 group_num = _print_relation(aobject);
2479 _finished_group(OBJECT, group_num);
2480 group_num = _print_state(aobject);
2481 _finished_group(OBJECT, group_num);
2483 if (top_tab == TEXT && ATK_IS_TEXT(aobject))
2485 group_num = _print_text(ATK_TEXT (aobject));
2486 _finished_group(TEXT, group_num);
2487 group_num = _print_text_attributes(ATK_TEXT (aobject));
2488 _finished_group(TEXT, group_num);
2490 if (top_tab == SELECTION && ATK_IS_SELECTION(aobject))
2492 group_num = _print_selection(ATK_SELECTION (aobject));
2493 _finished_group(SELECTION, group_num);
2495 if (top_tab == TABLE && ATK_IS_TABLE(aobject))
2497 group_num = _print_table(ATK_TABLE (aobject));
2498 _finished_group(TABLE, group_num);
2500 if (top_tab == ACTION && ATK_IS_ACTION(aobject))
2502 group_num = _print_action(ATK_ACTION (aobject));
2503 _finished_group(ACTION, group_num);
2505 if (top_tab == COMPONENT && ATK_IS_COMPONENT(aobject))
2507 group_num = _print_component(ATK_COMPONENT(aobject));
2508 _finished_group(COMPONENT, group_num);
2510 if (top_tab == IMAGE && ATK_IS_IMAGE(aobject))
2512 group_num = _print_image(ATK_IMAGE (aobject));
2513 _finished_group(IMAGE, group_num);
2515 if (top_tab == VALUE && ATK_IS_VALUE(aobject))
2517 group_num = _print_value(ATK_VALUE(aobject));
2518 _finished_group(VALUE, group_num);
2523 _update_current_page(GtkNotebook *notebook, gpointer p, guint current_page)
2525 _update(current_page+OBJECT, last_object);
2528 /* Property listeners */
2530 static void _property_change_handler (AtkObject *obj,
2531 AtkPropertyValues *values)
2533 TabNumber top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
2539 * Only process if the property change corrisponds to the current
2542 if (obj != last_object)
2546 g_print("\nProperty change event <%s> for object not in focus\n",
2547 values->property_name);
2555 g_print("\nProperty change event <%s> occurred.\n",
2556 values->property_name);
2560 * Update the top tab if a property changes.
2562 * We may be able to ignore some property changes if they do not
2563 * change anything in ferret.
2566 if (top_tab == OBJECT &&
2567 ((strcmp (values->property_name, "accessible-name") == 0) ||
2568 (strcmp (values->property_name, "accessible-description") == 0) ||
2569 (strcmp (values->property_name, "accessible-parent") == 0) ||
2570 (strcmp (values->property_name, "accessible-value") == 0) ||
2571 (strcmp (values->property_name, "accessible-role") == 0) ||
2572 (strcmp (values->property_name, "accessible-component-layout") == 0) ||
2573 (strcmp (values->property_name, "accessible-component-mdi-zorder") == 0) ||
2574 (strcmp (values->property_name, "accessible-table-caption") == 0) ||
2575 (strcmp (values->property_name,
2576 "accessible-table-column-description") == 0) ||
2577 (strcmp (values->property_name,
2578 "accessible-table-column-header") == 0) ||
2579 (strcmp (values->property_name,
2580 "accessible-table-row-description") == 0) ||
2581 (strcmp (values->property_name,
2582 "accessible-table-row-header") == 0) ||
2583 (strcmp (values->property_name, "accessible-table-summary") == 0)))
2586 g_print("Updating tab\n");
2588 _update(top_tab, last_object);
2590 else if (top_tab == VALUE &&
2591 (strcmp (values->property_name, "accessible-value") == 0))
2594 g_print("Updating tab\n");
2596 _update(top_tab, last_object);
2600 /* Action button callback function */
2602 void _action_cb(GtkWidget *widget, gpointer *userdata)
2604 NameValue *nv = (NameValue *)userdata;
2605 atk_action_do_action(ATK_ACTION(nv->atkobj), nv->action_num);
2608 /* Menu-bar callback functions */
2610 void _toggle_terminal(GtkCheckMenuItem *checkmenuitem,
2613 if (checkmenuitem->active)
2614 display_ascii = TRUE;
2616 display_ascii = FALSE;
2619 void _toggle_no_signals(GtkCheckMenuItem *checkmenuitem,
2622 if (checkmenuitem->active)
2628 void _toggle_magnifier(GtkCheckMenuItem *checkmenuitem,
2631 if (checkmenuitem->active)
2632 use_magnifier = TRUE;
2634 use_magnifier = FALSE;
2637 void _toggle_festival(GtkCheckMenuItem *checkmenuitem,
2640 if (checkmenuitem->active)
2641 use_festival = TRUE;
2643 use_festival = FALSE;
2646 void _toggle_festival_terse(GtkCheckMenuItem *checkmenuitem,
2649 if (checkmenuitem->active)
2661 void _toggle_trackmouse(GtkCheckMenuItem *checkmenuitem,
2664 if (checkmenuitem->active)
2666 mouse_watcher_focus_id =
2667 atk_add_global_event_listener(_mouse_watcher,
2668 "Gtk:GtkWidget:enter_notify_event");
2669 mouse_watcher_button_id =
2670 atk_add_global_event_listener(_button_watcher,
2671 "Gtk:GtkWidget:button_press_event");
2676 if (mouse_watcher_focus_id != -1)
2678 atk_remove_global_event_listener(mouse_watcher_focus_id);
2679 atk_remove_global_event_listener(mouse_watcher_button_id);
2680 track_mouse = FALSE;
2685 void _toggle_trackfocus(GtkCheckMenuItem *checkmenuitem,
2688 if (checkmenuitem->active)
2691 focus_tracker_id = atk_add_focus_tracker (_print_accessible);
2695 g_print ("No longer tracking focus.\n");
2696 track_focus = FALSE;
2697 atk_remove_focus_tracker (focus_tracker_id);