2 #undef GTK_DISABLE_DEPRECATED
3 #define GTK_ENABLE_BROKEN
5 #define MAX_NAME_VALUE 20
10 #include <netinet/in.h>
11 #include <sys/socket.h>
56 /* GUI Information for the group */
61 GtkFrame *scroll_outer_frame;
84 GtkHBox *column1, *column2, *hbox;
104 /* Function prototypes */
108 static void _init_data(void);
109 static void _create_window(void);
110 static void _add_menu(GtkWidget ** menu, GtkWidget ** menuitem,
111 gchar * name, gboolean init_value, GCallback func);
112 static void _clear_tab(TabNumber tab_n);
113 static void _greyout_tab (GtkWidget *widget, gboolean is_sensitive);
114 static void _finished_group(TabNumber tab_n, gint group_num);
115 static gboolean _object_is_ours (AtkObject *aobject);
116 static void _create_event_watcher (void);
118 /* Mouse Watcher/Magnifier/Festival functions */
120 static gboolean _mouse_watcher (GSignalInvocationHint *ihint,
121 guint n_param_values,
122 const GValue *param_values,
124 static gboolean _button_watcher (GSignalInvocationHint *ihint,
125 guint n_param_values,
126 const GValue *param_values,
128 static void _send_to_magnifier (gint x, gint y, gint w, gint h);
129 static void _send_to_festival (const gchar * name,
130 const gchar * role_name, const gchar * accel);
131 static void _speak_caret_event (AtkObject * aobject);
132 static void _festival_say (const gchar * text);
133 static void _festival_write (const gchar * text, int fd);
134 static gint _festival_init (void);
136 /* Update functions */
138 static void _update_current_page(GtkNotebook *notebook, gpointer p,
140 static void _update(TabNumber top_tab, AtkObject *aobject);
142 /* Print functions */
144 static void _print_accessible (AtkObject *aobject);
146 static gint _print_object (AtkObject *aobject);
147 static gint _print_relation (AtkObject *aobject);
148 static gint _print_state (AtkObject *aobject);
150 static gint _print_action (AtkAction *aobject);
151 static gint _print_component (AtkComponent *aobject);
152 static gint _print_image (AtkImage *aobject);
153 static gint _print_selection (AtkSelection *aobject);
154 static gint _print_table (AtkTable *aobject);
155 static gint _print_text (AtkText *aobject);
156 static gint _print_text_attributes (AtkText *aobject);
157 static gint _print_value (AtkValue *aobject);
158 static void _print_value_type(gint group_num, gchar *type, GValue *value);
159 static gint _print_groupname(TabNumber tab_n, GroupId group_id,
160 const char *groupname);
161 static NameValue* _print_key_value(TabNumber tab_n, gint group_number,
162 const char *label, gpointer value, ValueType type);
163 static void _print_signal(AtkObject *aobject, FerretSignalType type,
164 const char *name, const char *info);
166 /* Data Access functions */
168 static GroupInfo* _get_group(TabInfo *tab, GroupId group_id,
169 const gchar *groupname);
170 void _get_group_scrolled(GroupInfo *group);
171 static NameValue* _get_name_value(GroupInfo *group, const gchar *label,
172 gpointer value, ValueType type);
174 /* Signal handlers */
176 static void _update_handlers(AtkObject *obj);
177 static void _notify_text_insert_handler (GObject *obj,
178 int position, int offset);
179 static void _notify_text_delete_handler (GObject *obj,
180 int position, int offset);
181 static void _notify_caret_handler (GObject *obj, int position);
182 static void _notify_table_row_inserted (GObject *obj,
183 gint start_offset, gint length);
184 static void _notify_table_column_inserted (GObject *obj,
185 gint start_offset, gint length);
186 static void _notify_table_row_deleted (GObject *obj,
187 gint start_offset, gint length);
188 static void _notify_table_column_deleted (GObject *obj,
189 gint start_offset, gint length);
190 static void _notify_table_row_reordered (GObject *obj);
191 static void _notify_table_column_reordered (GObject *obj);
192 static void _notify_object_child_added (GObject *obj,
193 gint index, AtkObject *child);
194 static void _notify_object_child_removed (GObject *obj,
195 gint index, AtkObject *child);
196 static void _notify_object_state_change (GObject *obj,
197 gchar *name, gboolean set);
199 /* Property handlers */
201 static void _property_change_handler (AtkObject *obj,
202 AtkPropertyValues *values);
204 /* Ferret GUI callbacks */
206 void _action_cb(GtkWidget *widget, gpointer *userdata);
207 void _toggle_terminal(GtkCheckMenuItem *checkmenuitem,
209 void _toggle_no_signals(GtkCheckMenuItem *checkmenuitem,
211 void _toggle_magnifier(GtkCheckMenuItem *checkmenuitem,
213 void _toggle_festival(GtkCheckMenuItem *checkmenuitem,
215 void _toggle_festival_terse(GtkCheckMenuItem *checkmenuitem,
217 void _toggle_trackmouse(GtkCheckMenuItem *checkmenuitem,
219 void _toggle_trackfocus(GtkCheckMenuItem *checkmenuitem,
222 /* Global variables */
223 static GtkNotebook *notebook;
224 static TabInfo *nbook_tabs[END_TABS];
225 static gint mouse_watcher_focus_id = -1;
226 static gint mouse_watcher_button_id = -1;
227 static gint focus_tracker_id = -1;
228 static gboolean use_magnifier = FALSE;
229 static gboolean use_festival = FALSE;
230 static gboolean track_mouse = FALSE;
231 static gboolean track_focus = TRUE;
232 static gboolean say_role = TRUE;
233 static gboolean say_accel = TRUE;
234 static gboolean display_ascii = FALSE;
235 static gboolean no_signals = FALSE;
236 static gint last_caret_offset = 0;
238 static AtkObject *last_object = NULL;
239 static GtkWidget *mainWindow = NULL;
240 static GtkWidget *vbox1 = NULL;
241 static GtkWidget *menu = NULL;
242 static GtkWidget *menutop = NULL;
243 static GtkWidget *menubar = NULL;
244 static GtkWidget *menuitem_terminal = NULL;
245 static GtkWidget *menuitem_no_signals = NULL;
246 static GtkWidget *menuitem_magnifier = NULL;
247 static GtkWidget *menuitem_festival = NULL;
248 static GtkWidget *menuitem_festival_terse = NULL;
249 static GtkWidget *menuitem_trackmouse = NULL;
250 static GtkWidget *menuitem_trackfocus = NULL;
252 #ifdef HAVE_SOCKADDR_UN_SUN_LEN
253 static struct sockaddr_un mag_server = { 0, AF_UNIX , "/tmp/magnifier_socket" };
254 static struct sockaddr_un client = { 0 , AF_UNIX, "/tmp/mag_client"};
256 static struct sockaddr_un mag_server = { AF_UNIX , "/tmp/magnifier_socket" };
257 static struct sockaddr_un client = { AF_UNIX, "/tmp/mag_client"};
260 /* GUI Information for the output window */
263 GtkWindow *outputWindow;
267 GtkWidget *textInsert;
272 _send_to_magnifier(gint x, gint y, gint w, gint h)
274 int desc, length_msg;
277 sprintf (buff, "~5:%d,%d", x+w/2, y+h/2);
280 g_print ("sending magnifier: %s\n", buff);
283 #ifdef HAVE_SOCKADDR_UN_SUN_LEN
284 mag_server.sun_len = SUN_LEN(&mag_server);
285 client.sun_len = SUN_LEN(&client);
288 if((desc=socket(AF_UNIX,SOCK_STREAM,0)) == -1){
292 unlink("/tmp/mag_client");
294 if (bind(desc, (struct sockaddr*)&client, sizeof(client)) == -1)
300 if (connect(desc,(struct sockaddr*)&mag_server,sizeof(mag_server)) == -1)
306 length_msg = write(desc,buff,strlen(buff));
307 unlink("/tmp/mag_client");
311 static int _festival_init (void)
314 struct sockaddr_in name;
317 name.sin_family = AF_INET;
318 name.sin_port = htons (1314);
319 name.sin_addr.s_addr = htonl(INADDR_ANY);
320 fd = socket (PF_INET, SOCK_STREAM, 0);
322 while (connect(fd, (struct sockaddr *) &name, sizeof (name)) < 0) {
329 _festival_write ("(audio_mode'async)", fd);
333 static void _festival_say (const gchar *text)
339 const gchar *stretch;
341 fprintf (stderr, "saying %s\n", text);
345 fd = _festival_init ();
348 quoted = g_malloc(100+strlen(text)*2);
350 stretch = g_strdup (g_getenv ("FESTIVAL_STRETCH"));
351 if (!stretch) stretch = "0.75";
352 sprintf (prefix, "(audio_mode'shutup)\n (Parameter.set 'Duration_Stretch %s)\n (SayText \"", stretch);
354 strcpy(quoted, prefix);
355 p = quoted + strlen (prefix);
357 if ( *text == '\\' || *text == '"' )
365 _festival_write (quoted, fd);
371 static void _send_to_festival (const gchar *role_name,
372 const gchar *name, const gchar *accel)
375 int len = (strlen (role_name)+1 + strlen (name)+2 + 4 + strlen (accel)+2);
380 string = (gchar *) g_malloc (len * sizeof (gchar));
389 if (ch == '_') ch = ' ';
398 if (ch == '_') ch = ' ';
401 if ((say_accel) && (strlen (accel) > 0))
403 accel_name = (gchar *)accel;
404 if (strncmp (accel, "<C", 2) == 0)
406 accel_name = strncpy (accel_name, " control ", 9);
408 else if (strncmp (accel, " control", 5))
417 while (accel_name[j])
419 ch = accel_name[j++];
420 if (ch == '_') ch = ' ';
426 _festival_say (string);
430 static void _festival_write (const gchar *command_string, int fd)
436 write(fd, command_string, strlen(command_string));
439 static void _speak_caret_event (AtkObject *aobject)
442 gint caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
445 if (abs(caret_offset - last_caret_offset) > 1)
447 text = atk_text_get_text_at_offset (ATK_TEXT (aobject),
449 ATK_TEXT_BOUNDARY_LINE_START,
455 text = atk_text_get_text_before_offset (ATK_TEXT (aobject),
457 ATK_TEXT_BOUNDARY_CHAR,
461 _festival_say (text);
463 last_caret_offset = caret_offset;
467 _greyout_tab (GtkWidget *page_child, gboolean is_sensitive)
471 tab = gtk_notebook_get_tab_label (notebook, page_child);
473 gtk_widget_set_sensitive (GTK_WIDGET (tab), is_sensitive);
477 _refresh_notebook (AtkObject *aobject)
479 if (ATK_IS_OBJECT (aobject))
481 _greyout_tab (nbook_tabs[ACTION]->page, ATK_IS_ACTION(aobject));
482 _greyout_tab (nbook_tabs[COMPONENT]->page, ATK_IS_COMPONENT(aobject));
483 _greyout_tab (nbook_tabs[IMAGE]->page, ATK_IS_IMAGE(aobject));
484 _greyout_tab (nbook_tabs[SELECTION]->page, ATK_IS_SELECTION(aobject));
485 _greyout_tab (nbook_tabs[TABLE]->page, ATK_IS_TABLE(aobject));
486 _greyout_tab (nbook_tabs[TEXT]->page, ATK_IS_TEXT(aobject));
487 _greyout_tab (nbook_tabs[VALUE]->page, ATK_IS_VALUE(aobject));
491 static void _print_accessible (AtkObject *aobject)
495 if (_object_is_ours(aobject))
498 g_print("\nFocus entered the ferret output window!\n");
502 _refresh_notebook(aobject);
505 g_print("\nFocus change\n");
507 /* Do not attach signal handlers if the user has asked not to */
509 _update_handlers(aobject);
511 last_object = aobject; /* _update_handler normally does this */
513 top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
514 _update(top_tab, aobject);
521 if (ATK_IS_TEXT (aobject))
526 len = atk_text_get_character_count (ATK_TEXT (aobject));
527 atk_text_get_character_extents (ATK_TEXT (aobject), 0,
532 atk_text_get_character_extents (ATK_TEXT (aobject), len-1,
537 w = MAX (x0+w0, xN+wN) - x;
538 h = MAX (y0+h0, yN+hN) - y;
546 else if (ATK_IS_COMPONENT (aobject))
548 atk_component_get_extents (ATK_COMPONENT(aobject),
552 if (w > -1) _send_to_magnifier (x, y, w, h);
557 _object_is_ours (AtkObject *aobject)
559 /* determine whether this object is parented by our own accessible... */
561 AtkObject *toplevel = aobject;
563 while (atk_object_get_role(aobject) != ATK_ROLE_FRAME)
565 aobject = atk_object_get_parent (aobject);
566 if (aobject == NULL) break;
571 * Some widgets do not have an ATK_ROLE_FRAME at the top,
576 if (GTK_ACCESSIBLE(toplevel)->widget == mainWindow)
586 ferret_get_name_from_container (AtkObject *aobject)
589 gint n = atk_object_get_n_accessible_children (aobject);
592 while (!s && (i < n))
595 child = atk_object_ref_accessible_child (aobject, i);
596 if (ATK_IS_TEXT (child))
598 gint count = atk_text_get_character_count (ATK_TEXT (child));
599 s = atk_text_get_text (ATK_TEXT (child),
603 g_object_unref (child);
615 _print_object (AtkObject *aobject)
617 G_CONST_RETURN gchar * parent_name = NULL;
618 G_CONST_RETURN gchar * name = NULL;
619 G_CONST_RETURN gchar * description = NULL;
620 G_CONST_RETURN gchar * typename = NULL;
621 G_CONST_RETURN gchar * parent_typename = NULL;
622 G_CONST_RETURN gchar * role_name = NULL;
623 G_CONST_RETURN gchar * accel_name = NULL;
624 G_CONST_RETURN gchar * text = NULL;
626 AtkObject *parent = NULL;
627 static AtkObject *prev_aobject = NULL;
629 gint index_in_parent = -1;
632 TabNumber tab_n = OBJECT;
634 group_num = _print_groupname(tab_n, OBJECT_INTERFACE, "Object Interface");
636 name = atk_object_get_name (aobject);
637 typename = g_type_name (G_OBJECT_TYPE (aobject));
638 description = atk_object_get_description (aobject);
639 parent = atk_object_get_parent(aobject);
641 index_in_parent = atk_object_get_index_in_parent(aobject);
642 n_children = atk_object_get_n_accessible_children(aobject);
643 role = atk_object_get_role(aobject);
644 role_name = atk_role_get_name(role);
646 if (ATK_IS_ACTION (aobject))
648 accel_name = atk_action_get_keybinding (ATK_ACTION(aobject), 0);
649 if (!accel_name) accel_name = "";
656 if (GTK_IS_ACCESSIBLE (aobject) &&
657 GTK_IS_WIDGET (GTK_ACCESSIBLE (aobject)->widget))
659 _print_key_value(tab_n, group_num, "Widget name",
660 (gpointer)gtk_widget_get_name(GTK_ACCESSIBLE (aobject)->widget),
665 _print_key_value(tab_n, group_num, "Widget name", "No Widget",
671 _print_key_value(tab_n, group_num, "Accessible Type",
672 (gpointer)typename, VALUE_STRING);
676 _print_key_value(tab_n, group_num, "Accessible Type", "NULL",
682 _print_key_value(tab_n, group_num, "Accessible Name",
683 (gpointer)name, VALUE_STRING);
687 _print_key_value(tab_n, group_num, "Accessible Name", "(unknown)",
692 if (aobject != prev_aobject)
694 if (ATK_IS_TEXT (aobject) && !name)
697 atk_text_get_text_at_offset (ATK_TEXT (aobject),
699 ATK_TEXT_BOUNDARY_SENTENCE_END,
702 fprintf (stderr, "first sentence: %s\n", text);
703 _send_to_festival (role_name,
705 if (!name) name = "no name";
712 if (atk_object_get_role (aobject) == ATK_ROLE_TABLE_CELL)
714 gchar *cname = ferret_get_name_from_container (aobject);
715 if (cname) name = g_strdup (cname);
717 else if (atk_object_get_role (aobject) == ATK_ROLE_CHECK_BOX)
719 name = g_strdup ("check box");
726 _send_to_festival (role_name, name, accel_name);
733 parent_name = atk_object_get_name(parent);
735 parent_typename = g_type_name (G_OBJECT_TYPE (parent));
739 _print_key_value(tab_n, group_num, "Parent Accessible Type",
740 (gpointer)parent_typename, VALUE_STRING);
744 _print_key_value(tab_n, group_num,
745 "Parent Accessible Type", "NULL", VALUE_STRING);
750 _print_key_value(tab_n, group_num, "Parent Accessible Name",
751 (gpointer)parent_name, VALUE_STRING);
755 _print_key_value(tab_n, group_num,
756 "Parent Accessible Name", "NULL", VALUE_STRING);
759 output_str = g_strdup_printf("%d", index_in_parent);
760 _print_key_value(tab_n, group_num, "Index in Parent",
761 (gpointer)output_str, VALUE_STRING);
766 _print_key_value(tab_n, group_num, "Parent", "NULL", VALUE_STRING);
771 _print_key_value(tab_n, group_num, "Accessible Description",
772 (gpointer)description, VALUE_STRING);
776 _print_key_value(tab_n, group_num,
777 "Accessible Description", "NULL", VALUE_STRING);
782 _print_key_value(tab_n, group_num, "Accessible Role", (gpointer)role_name,
787 _print_key_value(tab_n, group_num, "Accessible Role", "NULL",
791 output_str = g_strdup_printf("%d", n_children);
792 _print_key_value(tab_n, group_num, "Number Children", (gpointer)output_str,
795 prev_aobject = aobject;
801 _print_relation (AtkObject *aobject)
803 AtkRelationSet* relation_set = atk_object_ref_relation_set (aobject);
804 gint n_relations = atk_relation_set_get_n_relations (relation_set);
806 TabNumber tab_n = OBJECT;
808 group_num = _print_groupname(tab_n, RELATION_INTERFACE,
809 "Relation Interface");
813 AtkRelation * relation;
814 G_CONST_RETURN gchar * relation_name = NULL;
815 G_CONST_RETURN gchar * relation_obj_name = NULL;
816 AtkRelationType relation_type;
817 AtkObject *relation_obj;
818 GPtrArray * relation_arry;
823 output_str = g_strdup_printf("%d", n_relations);
824 _print_key_value(tab_n, group_num,
825 "Number of Relations", (gpointer)output_str, VALUE_STRING);
828 for (i = 0; i < n_relations; i++)
830 relation = atk_relation_set_get_relation (relation_set, i);
832 relation_type = atk_relation_get_relation_type (relation);
833 relation_name = atk_relation_type_get_name (relation_type);
835 relation_arry = atk_relation_get_target(relation);
839 label_str = g_strdup_printf("Relation %d Name", i + 1);
840 _print_key_value(tab_n, group_num, label_str,
841 (gpointer)relation_name, VALUE_STRING);
846 label_str = g_strdup_printf("Relation %d Type", i + 1);
847 output_str = g_strdup_printf("%d", relation_type);
848 _print_key_value(tab_n, group_num, label_str,
849 (gpointer)output_str, VALUE_STRING);
854 label_str = g_strdup_printf("Relation %d with", i + 1);
855 output_str = g_strdup_printf("%d AtkObjects", relation_arry->len);
856 _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
861 for (j=0; j < relation_arry->len; j++)
863 label_str = g_strdup_printf(
864 "Relation %d,%d with AtkObject Name", i + 1, j + 1);
865 relation_obj = (AtkObject *)
866 g_ptr_array_index(relation_arry, j);
867 relation_obj_name = atk_object_get_name(relation_obj);
869 _print_key_value(tab_n, group_num, label_str,
870 (gpointer)relation_obj_name, VALUE_STRING);
875 g_object_unref (relation_set);
881 _print_state (AtkObject *aobject)
883 AtkStateSet *state_set = atk_object_ref_state_set(aobject);
885 TabNumber tab_n = OBJECT;
886 static AtkStateType states_to_track[] =
891 ATK_STATE_EXPANDABLE,
897 group_num = _print_groupname(tab_n, STATE_INTERFACE,
902 gboolean boolean_value;
903 AtkStateType one_state;
904 G_CONST_RETURN gchar *name;
907 for (i=0; i < sizeof(states_to_track)/sizeof(AtkStateType); i++)
909 one_state = (AtkStateType) states_to_track[i];
910 name = atk_state_type_get_name (one_state);
915 atk_state_set_contains_state (state_set, one_state);
916 _print_key_value(tab_n, group_num, name,
917 (gpointer)(&boolean_value), VALUE_BOOLEAN);
922 g_object_unref (state_set);
927 _print_action (AtkAction *aobject)
929 G_CONST_RETURN gchar *action_name;
930 G_CONST_RETURN gchar *action_description;
931 G_CONST_RETURN gchar *action_keybinding;
932 gchar *label_str, *output_str;
935 TabNumber tab_n = ACTION;
938 group_num = _print_groupname(tab_n, ACTION_INTERFACE,
941 num_actions = atk_action_get_n_actions (aobject);
942 output_str = g_strdup_printf("%d", num_actions);
943 _print_key_value(tab_n, group_num, "Number of Actions",
944 (gpointer) output_str, VALUE_STRING);
947 for (j = 0; j < num_actions; j++)
949 label_str = g_strdup_printf("Action %d Name", j + 1);
950 action_name = atk_action_get_name (aobject, j);
953 nv = _print_key_value(tab_n, group_num, label_str,
954 (gpointer) action_name, VALUE_BUTTON);
958 nv = _print_key_value(tab_n, group_num, label_str, "NULL",
962 nv->atkobj = ATK_OBJECT(aobject);
964 nv->signal_id = g_signal_connect (GTK_OBJECT (nv->button),
965 "clicked", G_CALLBACK (_action_cb), nv);
969 label_str = g_strdup_printf("Action %d Description", j + 1);
970 action_description = atk_action_get_description (aobject, j);
971 if (action_description)
973 _print_key_value(tab_n, group_num, label_str,
974 (gpointer)action_description, VALUE_STRING);
978 _print_key_value(tab_n, group_num, label_str, "NULL",
983 label_str = g_strdup_printf("Action %d Keybinding", j + 1);
984 action_keybinding = atk_action_get_keybinding (aobject, j);
985 if (action_keybinding)
987 _print_key_value(tab_n, group_num, label_str,
988 (gpointer)action_keybinding, VALUE_STRING);
992 _print_key_value(tab_n, group_num, label_str, "NULL",
1001 _print_component (AtkComponent *aobject)
1009 TabNumber tab_n = COMPONENT;
1011 group_num = _print_groupname(tab_n, COMPONENT_INTERFACE,
1012 "Component Interface");
1014 atk_component_get_extents (aobject,
1015 &x, &y, &width, &height, ATK_XY_SCREEN);
1017 output_str = g_strdup_printf("x: %d y: %d width: %d height %d",
1018 x, y, width, height);
1019 _print_key_value(tab_n, group_num, "Geometry", (gpointer)output_str,
1026 _print_image (AtkImage *aobject)
1028 G_CONST_RETURN gchar *image_desc;
1035 TabNumber tab_n = IMAGE;
1037 group_num = _print_groupname(tab_n, IMAGE_INTERFACE,
1040 image_desc = atk_image_get_image_description(aobject);
1043 _print_key_value(tab_n, group_num, "Description", (gpointer)image_desc,
1048 _print_key_value(tab_n, group_num, "Description", "NULL",
1052 atk_image_get_image_position(aobject, &x, &y, ATK_XY_SCREEN);
1053 atk_image_get_image_size(aobject, &height, &width);
1055 output_str = g_strdup_printf("x: %d y: %d width: %d height %d",
1056 x, y, width, height);
1057 _print_key_value(tab_n, group_num, "Geometry", (gpointer)output_str,
1064 _print_selection (AtkSelection *aobject)
1068 gchar *label_str, *output_str;
1070 gint n_selected, j, n_selectable;
1071 TabNumber tab_n = SELECTION;
1073 group_num = _print_groupname(tab_n, SELECTION_INTERFACE,
1074 "Selection Interface");
1076 n_selected = atk_selection_get_selection_count (aobject);
1077 output_str = g_strdup_printf ("%d", n_selected);
1078 _print_key_value (tab_n, group_num, "Number of Selected Children",
1079 (gpointer) output_str, VALUE_STRING);
1080 g_free (output_str);
1082 * The number of selected items is the number of children except for
1083 * a ComboBox where it is the number of items in the list.
1085 object = ATK_OBJECT (aobject);
1086 role = atk_object_get_role (object);
1087 if (role == ATK_ROLE_COMBO_BOX)
1089 object = atk_object_ref_accessible_child (object, 0);
1090 g_return_val_if_fail (atk_object_get_role (object) == ATK_ROLE_LIST,
1092 n_selectable = atk_object_get_n_accessible_children (object);
1093 g_object_unref (G_OBJECT (object));
1097 n_selectable = atk_object_get_n_accessible_children (object);
1099 output_str = g_strdup_printf ("%d", n_selectable);
1100 _print_key_value (tab_n, group_num, "Number of Selectable Children",
1101 (gpointer) output_str, VALUE_STRING);
1102 g_free (output_str);
1104 for (j = 0; j < n_selected; j++)
1106 G_CONST_RETURN gchar *selected_name;
1107 AtkObject *selected_object;
1109 selected_object = atk_selection_ref_selection (aobject, j);
1110 selected_name = atk_object_get_name (selected_object);
1111 if (selected_name == NULL)
1113 selected_name = "No name";
1115 label_str = g_strdup_printf ("Selected item: %d Name", j+1);
1116 _print_key_value (tab_n, group_num, label_str,
1117 (gpointer) selected_name, VALUE_STRING);
1119 g_object_unref (G_OBJECT (selected_object));
1125 _print_table (AtkTable *aobject)
1127 gchar *label_str, *output_str;
1128 G_CONST_RETURN gchar *col_desc;
1130 gint n_cols, n_rows;
1133 TabNumber tab_n = TABLE;
1135 group_num = _print_groupname(tab_n, TABLE_INTERFACE,
1138 n_cols = atk_table_get_n_columns(aobject);
1139 output_str = g_strdup_printf("%d", n_cols);
1140 _print_key_value(tab_n, group_num, "Number Columns", (gpointer)output_str,
1144 n_rows = atk_table_get_n_rows(aobject);
1145 output_str = g_strdup_printf("%d", n_rows);
1146 _print_key_value(tab_n, group_num, "Number Rows", (gpointer)output_str,
1150 caption = atk_table_get_caption(aobject);
1153 G_CONST_RETURN gchar* caption_name;
1155 caption_name = atk_object_get_name (caption);
1158 _print_key_value(tab_n, group_num, "Caption Name",
1159 (gpointer)caption_name, VALUE_STRING);
1163 for (i=0; i < n_cols; i++)
1165 label_str = g_strdup_printf("Column %d Description", i + 1);
1167 col_desc = atk_table_get_column_description(aobject, i);
1170 _print_key_value(tab_n, group_num, label_str, (gpointer)col_desc,
1175 _print_key_value(tab_n, group_num, label_str, "NULL",
1186 _print_text (AtkText *aobject)
1188 gchar *output_str, *text_val, *text_val_escaped;
1189 gint n_chars, caret_offset;
1190 gint start_offset, end_offset;
1193 TabNumber tab_n = TEXT;
1195 group_num = _print_groupname(tab_n, TEXT_INTERFACE,
1198 n_chars = atk_text_get_character_count(aobject);
1200 output_str = g_strdup_printf("%d", n_chars);
1201 _print_key_value(tab_n, group_num, "Total Character Count",
1202 (gpointer)output_str, VALUE_STRING);
1206 * Pass through g_strescape so that non-ASCII chars are made
1209 text_val = atk_text_get_text (aobject, 0, n_chars);
1212 text_val_escaped = g_strescape(text_val, NULL);
1213 _print_key_value (tab_n, group_num, "Text", (gpointer)text_val_escaped,
1216 g_free (text_val_escaped);
1220 _print_key_value (tab_n, group_num, "Text", "NULL", VALUE_TEXT);
1223 caret_offset = atk_text_get_caret_offset(aobject);
1224 output_str = g_strdup_printf("%d", caret_offset);
1225 _print_key_value(tab_n, group_num, "Caret Offset", (gpointer)output_str,
1229 if (caret_offset < 0)
1232 text_val = atk_text_get_text_at_offset (aobject, caret_offset,
1233 ATK_TEXT_BOUNDARY_CHAR,
1234 &start_offset, &end_offset);
1237 text_val_escaped = g_strescape(text_val, NULL);
1238 _print_key_value(tab_n, group_num, "Current Character",
1239 (gpointer)text_val_escaped, VALUE_STRING);
1241 g_free (text_val_escaped);
1245 _print_key_value(tab_n, group_num, "Current Character", "none",
1249 atk_text_get_character_extents (aobject, caret_offset,
1250 &x, &y, &w, &h, ATK_XY_SCREEN);
1251 output_str = g_strdup_printf ("(%d, %d) (%d, %d)", x, y, w, h);
1254 _print_key_value(tab_n, group_num, "Character Bounds (screen)",
1255 (gpointer)output_str, VALUE_STRING);
1259 atk_text_get_character_extents (aobject, caret_offset,
1260 &x, &y, &w, &h, ATK_XY_WINDOW);
1261 output_str = g_strdup_printf ("(%d, %d) (%d, %d)", x, y, w, h);
1264 _print_key_value(tab_n, group_num, "Character Bounds (window)",
1265 (gpointer)output_str, VALUE_STRING);
1269 text_val = atk_text_get_text_at_offset (aobject, caret_offset,
1270 ATK_TEXT_BOUNDARY_WORD_START,
1271 &start_offset, &end_offset);
1274 text_val_escaped = g_strescape(text_val, NULL);
1275 _print_key_value(tab_n, group_num, "Current Word",
1276 (gpointer)text_val_escaped, VALUE_STRING);
1278 g_free (text_val_escaped);
1282 _print_key_value(tab_n, group_num, "Current Word", "none",
1286 text_val = atk_text_get_text_at_offset (aobject, caret_offset,
1287 ATK_TEXT_BOUNDARY_LINE_START,
1288 &start_offset, &end_offset);
1291 text_val_escaped = g_strescape(text_val, NULL);
1292 _print_key_value(tab_n, group_num, "Current Line",
1293 (gpointer)text_val_escaped, VALUE_STRING);
1295 g_free (text_val_escaped);
1299 _print_key_value(tab_n, group_num, "Current Line", "none",
1303 text_val = atk_text_get_text_at_offset (aobject, caret_offset,
1304 ATK_TEXT_BOUNDARY_SENTENCE_START,
1305 &start_offset, &end_offset);
1308 text_val_escaped = g_strescape(text_val, NULL);
1309 _print_key_value(tab_n, group_num, "Current Sentence",
1310 (gpointer)text_val_escaped, VALUE_STRING);
1312 g_free (text_val_escaped);
1316 _print_key_value(tab_n, group_num, "Current Line", "none",
1323 _print_text_attributes (AtkText *aobject)
1325 AtkAttributeSet *attribute_set;
1326 AtkAttribute *attribute;
1327 gchar *output_str, *label_str;
1328 gint start_offset, end_offset, caret_offset;
1329 gint attribute_set_len, attribute_offset, i;
1332 TabNumber tab_n = TEXT;
1334 n_chars = atk_text_get_character_count(aobject);
1336 group_num = _print_groupname (tab_n, TEXT_ATTRIBUTES,
1337 "Text Attributes at Caret");
1339 caret_offset = atk_text_get_caret_offset(aobject);
1340 attribute_offset = caret_offset;
1345 attribute_set = atk_text_get_run_attributes(aobject, attribute_offset,
1346 &start_offset, &end_offset);
1348 label_str = g_strdup_printf("Attribute run start");
1350 output_str = g_strdup_printf("%d", start_offset);
1351 _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
1356 label_str = g_strdup_printf("Attribute run end");
1357 output_str = g_strdup_printf("%d", end_offset);
1358 _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
1363 if (attribute_set == NULL)
1364 attribute_set_len = 0;
1366 attribute_set_len = g_slist_length(attribute_set);
1368 label_str = g_strdup_printf("Number of Attributes");
1369 output_str = g_strdup_printf("%d", attribute_set_len);
1370 _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
1375 for (i=0; i < attribute_set_len; i++)
1377 attribute = ((AtkAttribute *) g_slist_nth(attribute_set, i)->data);
1379 _print_key_value(tab_n, group_num, attribute->name,
1380 (gpointer)attribute->value, VALUE_STRING);
1382 if (attribute_set != NULL)
1383 atk_attribute_set_free(attribute_set);
1390 _print_value (AtkValue *aobject)
1392 GValue *value_back, val;
1394 TabNumber tab_n = VALUE;
1398 group_num = _print_groupname(tab_n, VALUE_INTERFACE,
1401 atk_value_get_current_value(aobject, value_back);
1402 _print_value_type(group_num, "Value", value_back);
1403 atk_value_get_minimum_value(aobject, value_back);
1404 _print_value_type(group_num, "Minimum Value", value_back);
1405 atk_value_get_maximum_value(aobject, value_back);
1406 _print_value_type(group_num, "Maximum Value", value_back);
1411 _print_value_type(gint group_num, gchar *type, GValue *value)
1413 gchar *label_str = NULL;
1414 gchar *output_str = NULL;
1415 TabNumber tab_n = VALUE;
1417 if (G_VALUE_HOLDS_DOUBLE (value))
1419 label_str = g_strdup_printf("%s - Double", type);
1420 output_str = g_strdup_printf("%f",
1421 g_value_get_double (value));
1422 _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
1425 else if (G_VALUE_HOLDS_INT (value))
1427 label_str = g_strdup_printf("%s - Integer", type);
1428 output_str = g_strdup_printf("%d",
1429 g_value_get_int (value));
1430 _print_key_value(tab_n, group_num, label_str, (gpointer)output_str,
1435 _print_key_value(tab_n, group_num, "Value", "Unknown Type",
1446 _create_event_watcher (void)
1448 focus_tracker_id = atk_add_focus_tracker (_print_accessible);
1452 mouse_watcher_focus_id =
1453 atk_add_global_event_listener(_mouse_watcher,
1454 "Gtk:GtkWidget:enter_notify_event");
1455 mouse_watcher_button_id =
1456 atk_add_global_event_listener(_button_watcher,
1457 "Gtk:GtkWidget:button_press_event");
1462 _mouse_watcher (GSignalInvocationHint *ihint,
1463 guint n_param_values,
1464 const GValue *param_values,
1470 object = g_value_get_object (param_values + 0);
1472 if (GTK_IS_MENU(object)) return TRUE;
1474 g_assert (GTK_IS_WIDGET(object));
1476 widget = GTK_WIDGET (object);
1477 if (GTK_IS_WINDOW (widget))
1479 GtkWidget *focus_widget = GTK_WINDOW (widget)->focus_widget;
1480 if (focus_widget != NULL)
1481 widget = focus_widget;
1484 _print_accessible (gtk_widget_get_accessible (widget));
1489 _button_watcher (GSignalInvocationHint *ihint,
1490 guint n_param_values,
1491 const GValue *param_values,
1497 object = g_value_get_object (param_values + 0);
1499 widget = GTK_WIDGET (object);
1500 if (GTK_IS_CONTAINER (widget))
1502 if (G_VALUE_HOLDS_BOXED (param_values + 1))
1504 GdkEventButton *event;
1508 gint aobject_x, aobject_y;
1511 gp = g_value_get_boxed (param_values + 1);
1512 event = (GdkEventButton *) gp;
1513 aobject = gtk_widget_get_accessible (widget);
1514 aobject_x = aobject_y = 0;
1515 atk_component_get_position (ATK_COMPONENT (aobject),
1516 &aobject_x, &aobject_y,
1518 x = aobject_x + (gint) event->x;
1519 y = aobject_y + (gint) event->y;
1520 child = atk_component_ref_accessible_at_point (ATK_COMPONENT (aobject),
1526 _print_accessible (child);
1527 g_object_unref (child);
1531 if (!GTK_IS_MENU_ITEM (widget))
1533 g_print ("No child at position %d %d for %s\n",
1536 g_type_name (G_OBJECT_TYPE (widget)));
1545 static void _add_notebook_page (GtkNotebook *nbook,
1546 GtkWidget *content_widget,
1547 GtkWidget **new_page,
1548 const gchar *label_text)
1552 if (content_widget != NULL)
1554 *new_page = content_widget;
1558 *new_page = gtk_vpaned_new ();
1561 label = gtk_label_new ("");
1562 gtk_label_set_markup_with_mnemonic (GTK_LABEL (label), label_text);
1563 gtk_notebook_append_page (notebook, *new_page, label);
1564 gtk_widget_show(*new_page);
1568 _create_notebook (void)
1571 notebook = GTK_NOTEBOOK (gtk_notebook_new());
1573 tab = nbook_tabs[OBJECT];
1574 _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Object</b>");
1576 tab = nbook_tabs[ACTION];
1577 _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Action</b>");
1579 tab = nbook_tabs[COMPONENT];
1580 _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Component</b>");
1582 tab = nbook_tabs[IMAGE];
1583 _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Image</b>");
1585 tab = nbook_tabs[SELECTION];
1586 _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Selection</b>");
1588 tab = nbook_tabs[TABLE];
1589 _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Table</b>");
1591 tab = nbook_tabs[TEXT];
1592 _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>Te_xt</b>");
1594 tab = nbook_tabs[VALUE];
1595 _add_notebook_page (notebook, tab->main_box, &tab->page, "<b>_Value</b>");
1597 g_signal_connect (GTK_OBJECT (notebook),
1599 G_CALLBACK (_update_current_page),
1608 the_tab = g_new0(TabInfo, 1);
1609 the_tab->page = NULL;
1610 the_tab->main_box = gtk_vbox_new(FALSE, 20);
1611 the_tab->name = "Object";
1612 nbook_tabs[OBJECT] = the_tab;
1614 the_tab = g_new0(TabInfo, 1);
1615 the_tab->page = NULL;
1616 the_tab->main_box = gtk_vbox_new(FALSE, 20);
1617 the_tab->name = "Action";
1618 nbook_tabs[ACTION] = the_tab;
1620 the_tab = g_new0(TabInfo, 1);
1621 the_tab->page = NULL;
1622 the_tab->main_box = gtk_vbox_new(FALSE, 20);
1623 the_tab->name = "Component";
1624 nbook_tabs[COMPONENT] = the_tab;
1626 the_tab = g_new0(TabInfo, 1);
1627 the_tab->page = NULL;
1628 the_tab->main_box = gtk_vbox_new(FALSE, 20);
1629 the_tab->name = "Image";
1630 nbook_tabs[IMAGE] = the_tab;
1632 the_tab = g_new0(TabInfo, 1);
1633 the_tab->page = NULL;
1634 the_tab->main_box = gtk_vbox_new(FALSE, 20);
1635 the_tab->name = "Selection";
1636 nbook_tabs[SELECTION] = the_tab;
1638 the_tab = g_new0(TabInfo, 1);
1639 the_tab->page = NULL;
1640 the_tab->main_box = gtk_vbox_new(FALSE, 20);
1641 the_tab->name = "Table";
1642 nbook_tabs[TABLE] = the_tab;
1644 the_tab = g_new0(TabInfo, 1);
1645 the_tab->page = NULL;
1646 the_tab->main_box = gtk_vbox_new(FALSE, 20);
1647 the_tab->name = "Text";
1648 nbook_tabs[TEXT] = the_tab;
1650 the_tab = g_new0(TabInfo, 1);
1651 the_tab->page = NULL;
1652 the_tab->main_box = gtk_vbox_new(FALSE, 20);
1653 the_tab->name = "Value";
1654 nbook_tabs[VALUE] = the_tab;
1658 _create_window (void)
1660 static GtkWidget *window = NULL;
1664 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1665 gtk_widget_set_name (window, "Ferret Window");
1666 gtk_window_set_policy (GTK_WINDOW(window), TRUE, TRUE, FALSE);
1668 g_signal_connect (GTK_OBJECT (window), "destroy",
1669 G_CALLBACK (gtk_widget_destroyed),
1672 gtk_window_set_title (GTK_WINDOW (window), "GTK+ Ferret Output");
1673 gtk_window_set_default_size (GTK_WINDOW (window), 333, 550);
1674 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1676 vbox1 = gtk_vbox_new (FALSE, 0);
1677 gtk_container_add (GTK_CONTAINER (window), vbox1);
1678 gtk_widget_show (vbox1);
1680 menubar = gtk_menu_bar_new ();
1681 gtk_box_pack_start (GTK_BOX (vbox1), menubar, FALSE, TRUE, 0);
1682 gtk_widget_show (menubar);
1683 menutop = gtk_menu_item_new_with_label("Menu");
1684 gtk_menu_bar_append(GTK_MENU_BAR(menubar), menutop);
1685 gtk_widget_show (menutop);
1686 menu = gtk_menu_new();
1687 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menutop), menu);
1688 gtk_widget_show (menu);
1690 _add_menu(&menu, &menuitem_trackmouse, "Track Mouse", track_mouse,
1691 G_CALLBACK(_toggle_trackmouse));
1692 _add_menu(&menu, &menuitem_trackfocus, "Track Focus", track_focus,
1693 G_CALLBACK(_toggle_trackfocus));
1694 _add_menu(&menu, &menuitem_magnifier, "Magnifier", use_magnifier,
1695 G_CALLBACK(_toggle_magnifier));
1696 _add_menu(&menu, &menuitem_festival, "Festival", use_festival,
1697 G_CALLBACK(_toggle_festival));
1698 _add_menu(&menu, &menuitem_festival_terse, "Festival Terse",
1699 (!say_role && !say_accel),
1700 G_CALLBACK(_toggle_festival_terse));
1701 _add_menu(&menu, &menuitem_terminal, "Terminal Output", display_ascii,
1702 G_CALLBACK(_toggle_terminal));
1703 _add_menu(&menu, &menuitem_no_signals, "No ATK Signals", no_signals,
1704 G_CALLBACK(_toggle_no_signals));
1706 _create_notebook ();
1707 gtk_container_add (GTK_CONTAINER (vbox1), GTK_WIDGET (notebook));
1708 gtk_widget_show (GTK_WIDGET (notebook));
1710 if (!GTK_WIDGET_VISIBLE (window))
1711 gtk_widget_show (window);
1713 mainWindow = GTK_WIDGET (window);
1717 _add_menu(GtkWidget ** menu, GtkWidget ** menuitem, gchar * name,
1718 gboolean init_value, GCallback func)
1720 *menuitem = gtk_check_menu_item_new_with_label(name);
1721 gtk_check_menu_item_set_active(
1722 GTK_CHECK_MENU_ITEM(*menuitem), init_value);
1723 gtk_menu_shell_append (GTK_MENU_SHELL (*menu), *menuitem);
1724 gtk_widget_show(*menuitem);
1725 g_signal_connect(GTK_OBJECT(*menuitem), "toggled", func, NULL);
1729 gtk_module_init(gint argc, char* argv[])
1731 if (g_getenv ("FERRET_ASCII"))
1732 display_ascii = TRUE;
1734 if (g_getenv ("FERRET_NOSIGNALS"))
1738 g_print("GTK ferret Module loaded\n");
1740 if (g_getenv("FERRET_MAGNIFIER"))
1741 use_magnifier = TRUE;
1743 if (g_getenv ("FERRET_FESTIVAL"))
1744 use_festival = TRUE;
1746 if (g_getenv ("FERRET_MOUSETRACK"))
1749 if (g_getenv ("FERRET_TERSE"))
1759 _create_event_watcher();
1765 _clear_tab(TabNumber tab_n)
1767 GList *group_list, *nv_list;
1772 tab = nbook_tabs[tab_n];
1774 for (group_list = tab->groups; group_list; group_list = group_list->next)
1776 group = (GroupInfo *) group_list->data;
1778 if (group->is_scrolled)
1779 gtk_widget_hide(GTK_WIDGET(group->scroll_outer_frame));
1781 gtk_widget_hide(GTK_WIDGET(group->frame));
1782 gtk_widget_hide(GTK_WIDGET(group->group_vbox));
1784 for (nv_list = group->name_value; nv_list; nv_list = nv_list->next)
1786 nv = (NameValue *) nv_list->data;
1788 gtk_widget_hide(GTK_WIDGET(nv->column1));
1789 gtk_widget_hide(GTK_WIDGET(nv->column2));
1790 gtk_widget_hide(GTK_WIDGET(nv->label));
1795 gtk_widget_hide(GTK_WIDGET(nv->string));
1798 gtk_widget_hide(GTK_WIDGET(nv->boolean));
1801 gtk_widget_hide(GTK_WIDGET(nv->text));
1804 gtk_widget_hide(GTK_WIDGET(nv->button));
1807 gtk_widget_hide(GTK_WIDGET(nv->hbox));
1809 /* Disconnect signal handler if any */
1810 if (nv->signal_id != -1)
1811 g_signal_handler_disconnect(nv->button, nv->signal_id);
1819 _print_groupname(TabNumber tab_n, GroupId group_id,
1820 const char *groupname)
1823 GroupInfo *the_group;
1827 g_print("\n<%s>\n", groupname);
1829 tab = nbook_tabs[tab_n];
1830 the_group = _get_group(tab, group_id, groupname);
1831 rc = g_list_index(tab->groups, the_group);
1836 _get_group(TabInfo *tab, GroupId group_id, const gchar *groupname)
1838 GroupInfo *group = NULL;
1839 gboolean found = FALSE;
1842 for (group_list = tab->groups; group_list; group_list = group_list->next)
1844 group = (GroupInfo *) group_list->data;
1845 if (group_id == group->group_id)
1854 /* build a new one */
1855 group = (GroupInfo *)g_new0(GroupInfo, 1);
1856 group->group_id = group_id;
1857 _get_group_scrolled(group);
1859 if (group->is_scrolled)
1861 group->frame = gtk_scrolled_window_new (NULL, NULL);
1862 gtk_widget_set_size_request (GTK_WIDGET (group->frame), -2,
1863 group->default_height);
1864 group->scroll_outer_frame = GTK_FRAME(gtk_frame_new(groupname));
1865 gtk_container_add(GTK_CONTAINER(group->scroll_outer_frame),
1870 group->frame = gtk_frame_new(groupname);
1873 gtk_container_set_border_width(GTK_CONTAINER(group->frame), 10);
1875 group->name = g_strdup(groupname);
1876 group->group_vbox = GTK_VBOX(gtk_vbox_new(FALSE, 10));
1878 if (group->is_scrolled)
1880 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (group->frame),
1881 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1882 gtk_scrolled_window_add_with_viewport(
1883 GTK_SCROLLED_WINDOW(group->frame),
1884 GTK_WIDGET(group->group_vbox));
1888 gtk_container_add(GTK_CONTAINER(group->frame),
1889 GTK_WIDGET(group->group_vbox));
1892 tab->groups = g_list_append (tab->groups, group);
1894 if (group->is_scrolled)
1896 gtk_box_pack_start (GTK_BOX (tab->main_box),
1897 GTK_WIDGET (group->scroll_outer_frame),
1902 gtk_box_pack_start (GTK_BOX (tab->main_box),
1903 GTK_WIDGET (group->frame),
1912 _get_group_scrolled(GroupInfo *group)
1914 if (group->group_id == OBJECT_INTERFACE)
1916 group->is_scrolled = FALSE;
1918 else if (group->group_id == RELATION_INTERFACE)
1920 group->is_scrolled = TRUE;
1921 group->default_height = 50;
1923 else if (group->group_id == STATE_INTERFACE)
1925 group->is_scrolled = TRUE;
1926 group->default_height = 100;
1928 else if (group->group_id == ACTION_INTERFACE)
1930 group->is_scrolled = TRUE;
1931 group->default_height = 200;
1933 else if (group->group_id == TEXT_ATTRIBUTES)
1935 group->is_scrolled = TRUE;
1936 group->default_height = 70;
1940 group->is_scrolled = FALSE;
1945 _get_name_value(GroupInfo *group, const gchar *label,
1946 gpointer value_ptr, ValueType type)
1948 NameValue *name_value = NULL;
1951 gboolean found = FALSE;
1952 static char *empty_string = "";
1956 label = empty_string;
1959 for (nv_list = group->name_value; nv_list; nv_list = nv_list->next)
1961 name_value = (NameValue *) nv_list->data;
1962 if (!name_value->active)
1971 name_value = (NameValue *)g_new0(NameValue, 1);
1972 name_value->column1 = GTK_HBOX(gtk_hbox_new(FALSE, 10));
1973 name_value->column2 = GTK_HBOX(gtk_hbox_new(FALSE, 10));
1974 name_value->hbox = GTK_HBOX(gtk_hbox_new(FALSE, 5));
1975 name_value->label = GTK_LABEL(gtk_label_new(label));
1976 name_value->string = gtk_label_new (NULL);
1977 name_value->boolean = gtk_check_button_new ();
1978 name_value->text = gtk_entry_new_with_max_length (1000);
1979 name_value->button = GTK_BUTTON(gtk_button_new ());
1981 gtk_box_pack_end(GTK_BOX(name_value->column1),
1982 GTK_WIDGET(name_value->label), FALSE, FALSE, 10);
1987 gtk_label_set_text(GTK_LABEL(name_value->string),
1988 (gchar *) value_ptr);
1989 gtk_box_pack_start(GTK_BOX(name_value->column2),
1990 GTK_WIDGET(name_value->string), FALSE, FALSE, 10);
1993 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(name_value->boolean),
1994 *((gboolean *)value_ptr));
1995 gtk_widget_set_sensitive(name_value->boolean, FALSE);
1996 gtk_box_pack_start(GTK_BOX(name_value->column2),
1997 GTK_WIDGET(name_value->boolean), FALSE, FALSE, 10);
2000 gtk_entry_set_text (GTK_ENTRY (name_value->text),
2001 (gchar *)value_ptr);
2002 gtk_box_pack_start(GTK_BOX(name_value->column2),
2003 GTK_WIDGET(name_value->text), FALSE, FALSE, 10);
2005 value = &(name_value->button_gval);
2006 memset (value, 0, sizeof (GValue));
2007 g_value_init (value, G_TYPE_STRING);
2008 g_value_set_string (value, (gchar *)value_ptr);
2009 g_object_set_property(G_OBJECT(name_value->button),
2011 gtk_box_pack_start(GTK_BOX(name_value->column2),
2012 GTK_WIDGET(name_value->button), FALSE, FALSE, 10);
2016 gtk_box_pack_start (GTK_BOX (name_value->hbox),
2017 GTK_WIDGET (name_value->column1),
2019 gtk_box_pack_start (GTK_BOX (name_value->hbox),
2020 GTK_WIDGET (name_value->column2),
2022 gtk_container_add(GTK_CONTAINER(group->group_vbox),
2023 GTK_WIDGET(name_value->hbox));
2024 group->name_value = g_list_append (group->name_value, name_value);
2028 gtk_label_set_text(GTK_LABEL(name_value->label), label);
2032 gtk_label_set_text(GTK_LABEL(name_value->string),
2033 (gchar *) value_ptr);
2036 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(name_value->boolean),
2037 *((gboolean *)value_ptr));
2038 gtk_widget_set_sensitive(name_value->boolean, FALSE);
2041 gtk_entry_set_text (GTK_ENTRY (name_value->text),
2042 (gchar *) value_ptr);
2045 value = &(name_value->button_gval);
2046 memset (value, 0, sizeof (GValue));
2047 g_value_init (value, G_TYPE_STRING);
2048 g_value_set_string (value, (gchar *)value_ptr);
2049 g_object_set_property(G_OBJECT(name_value->button),
2055 name_value->active = TRUE;
2056 name_value->type = type;
2057 name_value->signal_id = -1;
2059 gtk_widget_show(GTK_WIDGET(name_value->label));
2064 gtk_widget_show(GTK_WIDGET(name_value->string));
2067 gtk_widget_show(GTK_WIDGET(name_value->boolean));
2070 gtk_widget_show(GTK_WIDGET(name_value->text));
2073 gtk_widget_show(GTK_WIDGET(name_value->button));
2077 gtk_widget_show(GTK_WIDGET(name_value->column1));
2078 gtk_widget_show(GTK_WIDGET(name_value->column2));
2079 gtk_widget_show(GTK_WIDGET(name_value->hbox));
2080 gtk_widget_show(GTK_WIDGET(group->group_vbox));
2086 _print_key_value(TabNumber tab_n, gint group_number,
2087 const char *label, gpointer value, ValueType type)
2090 GroupInfo *the_group;
2094 if (type == VALUE_BOOLEAN)
2096 if (*((gboolean *)value))
2097 g_print("\t%-30s\tTRUE\n", label);
2099 g_print("\t%-30s\tFALSE\n", label);
2103 g_print("\t%-30s\t%s\n", label,
2104 value ? (gchar *)value : "NULL");
2108 tab = nbook_tabs[tab_n];
2109 the_group = (GroupInfo *)g_list_nth_data(tab->groups, group_number);
2110 return _get_name_value(the_group, label, (gpointer)value, type);
2114 _finished_group(TabNumber tab_no, gint group_number)
2117 GroupInfo *the_group;
2119 tab = nbook_tabs[tab_no];
2121 the_group = (GroupInfo *)g_list_nth_data(tab->groups, group_number);
2123 if (the_group->is_scrolled)
2124 gtk_widget_show(GTK_WIDGET(the_group->scroll_outer_frame));
2126 gtk_widget_show(GTK_WIDGET(the_group->frame));
2127 gtk_widget_show(GTK_WIDGET(the_group->group_vbox));
2128 gtk_widget_show(GTK_WIDGET(tab->main_box));
2131 /* Signal handlers */
2133 static gulong child_added_id = 0;
2134 static gulong child_removed_id = 0;
2135 static gulong state_change_id = 0;
2137 static gulong text_caret_handler_id = 0;
2138 static gulong text_inserted_id = 0;
2139 static gulong text_deleted_id = 0;
2141 static gulong table_row_inserted_id = 0;
2142 static gulong table_column_inserted_id = 0;
2143 static gulong table_row_deleted_id = 0;
2144 static gulong table_column_deleted_id = 0;
2145 static gulong table_row_reordered_id = 0;
2146 static gulong table_column_reordered_id = 0;
2148 static gulong property_id = 0;
2151 _update_handlers(AtkObject *obj)
2153 /* Remove signal handlers from object that had focus before */
2155 if (last_object != NULL && G_TYPE_CHECK_INSTANCE(last_object))
2157 if (child_added_id != 0)
2158 g_signal_handler_disconnect(last_object, child_added_id);
2159 if (child_removed_id != 0)
2160 g_signal_handler_disconnect(last_object, child_removed_id);
2161 if (state_change_id != 0)
2162 g_signal_handler_disconnect(last_object, state_change_id);
2164 if (text_caret_handler_id != 0)
2165 g_signal_handler_disconnect(last_object, text_caret_handler_id);
2166 if (text_inserted_id != 0)
2167 g_signal_handler_disconnect(last_object, text_inserted_id);
2168 if (text_deleted_id != 0)
2169 g_signal_handler_disconnect(last_object, text_deleted_id);
2171 if (table_row_inserted_id != 0)
2172 g_signal_handler_disconnect(last_object, table_row_inserted_id);
2173 if (table_column_inserted_id != 0)
2174 g_signal_handler_disconnect(last_object, table_column_inserted_id);
2175 if (table_row_deleted_id != 0)
2176 g_signal_handler_disconnect(last_object, table_row_deleted_id);
2177 if (table_column_deleted_id != 0)
2178 g_signal_handler_disconnect(last_object, table_column_deleted_id);
2179 if (table_row_reordered_id != 0)
2180 g_signal_handler_disconnect(last_object, table_row_reordered_id);
2181 if (table_column_reordered_id != 0)
2182 g_signal_handler_disconnect(last_object, table_column_reordered_id);
2183 if (property_id != 0)
2184 g_signal_handler_disconnect(last_object, property_id);
2186 g_object_unref(last_object);
2192 child_removed_id = 0;
2193 text_caret_handler_id = 0;
2194 text_inserted_id = 0;
2195 text_deleted_id = 0;
2196 table_row_inserted_id = 0;
2197 table_column_inserted_id = 0;
2198 table_row_deleted_id = 0;
2199 table_column_deleted_id = 0;
2200 table_row_reordered_id = 0;
2201 table_column_reordered_id = 0;
2204 if (!G_TYPE_CHECK_INSTANCE(obj))
2210 /* Add signal handlers to object that now has focus. */
2212 if (ATK_IS_OBJECT(obj))
2214 child_added_id = g_signal_connect_closure (obj,
2215 "children_changed::add",
2216 g_cclosure_new (G_CALLBACK (_notify_object_child_added),
2217 NULL, NULL), FALSE);
2219 child_removed_id = g_signal_connect_closure (obj,
2220 "children_changed::remove",
2221 g_cclosure_new (G_CALLBACK (_notify_object_child_removed),
2222 NULL, NULL), FALSE);
2224 state_change_id = g_signal_connect_closure (obj,
2226 g_cclosure_new (G_CALLBACK (_notify_object_state_change),
2227 NULL, NULL), FALSE);
2230 if (ATK_IS_TEXT(obj))
2232 text_caret_handler_id = g_signal_connect_closure_by_id (obj,
2233 g_signal_lookup ("text_caret_moved", G_OBJECT_TYPE (obj)),
2234 0, g_cclosure_new (G_CALLBACK (_notify_caret_handler),
2235 NULL, NULL), FALSE);
2236 text_inserted_id = g_signal_connect_closure (obj,
2237 "text_changed::insert",
2238 g_cclosure_new (G_CALLBACK (_notify_text_insert_handler),
2239 NULL, NULL), FALSE);
2240 text_deleted_id = g_signal_connect_closure (obj,
2241 "text_changed::delete",
2242 g_cclosure_new (G_CALLBACK (_notify_text_delete_handler),
2243 NULL, NULL), FALSE);
2246 if (ATK_IS_TABLE(obj))
2248 table_row_inserted_id = g_signal_connect_closure_by_id (obj,
2249 g_signal_lookup ("row_inserted", G_OBJECT_TYPE (obj)),
2250 0, g_cclosure_new (G_CALLBACK (_notify_table_row_inserted),
2251 NULL, NULL), FALSE);
2252 table_column_inserted_id = g_signal_connect_closure_by_id (obj,
2253 g_signal_lookup ("column_inserted", G_OBJECT_TYPE (obj)),
2254 0, g_cclosure_new (G_CALLBACK (_notify_table_column_inserted),
2255 NULL, NULL), FALSE);
2256 table_row_deleted_id = g_signal_connect_closure_by_id (obj,
2257 g_signal_lookup ("row_deleted", G_OBJECT_TYPE (obj)),
2258 0, g_cclosure_new (G_CALLBACK (_notify_table_row_deleted),
2259 NULL, NULL), FALSE);
2260 table_column_deleted_id = g_signal_connect_closure_by_id (obj,
2261 g_signal_lookup ("column_deleted", G_OBJECT_TYPE (obj)),
2262 0, g_cclosure_new (G_CALLBACK (_notify_table_column_deleted),
2263 NULL, NULL), FALSE);
2264 table_row_reordered_id = g_signal_connect_closure_by_id (obj,
2265 g_signal_lookup ("row_reordered", G_OBJECT_TYPE (obj)),
2266 0, g_cclosure_new (G_CALLBACK (_notify_table_row_reordered),
2267 NULL, NULL), FALSE);
2268 table_column_reordered_id = g_signal_connect_closure_by_id (obj,
2269 g_signal_lookup ("column_reordered", G_OBJECT_TYPE (obj)),
2270 0, g_cclosure_new (G_CALLBACK (_notify_table_column_reordered),
2271 NULL, NULL), FALSE);
2274 property_id = g_signal_connect_closure_by_id (obj,
2275 g_signal_lookup ("property_change", G_OBJECT_TYPE (obj)),
2276 0, g_cclosure_new (G_CALLBACK (_property_change_handler),
2284 _notify_text_insert_handler (GObject *obj, int position, int offset)
2286 gchar *text = atk_text_get_text (ATK_TEXT (obj), position, position + offset);
2287 gchar *output_str = g_strdup_printf("position %d, length %d text: %s",
2288 position, offset, text ? text: "<NULL>");
2289 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
2290 "Text Insert", output_str);
2295 _notify_text_delete_handler (GObject *obj, int position, int offset)
2297 gchar *text = atk_text_get_text (ATK_TEXT (obj), position, position + offset);
2298 gchar *output_str = g_strdup_printf("position %d, length %d text: %s",
2299 position, offset, text ? text: "<NULL>");
2300 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
2301 "Text Delete", output_str);
2306 _notify_caret_handler (GObject *obj, int position)
2308 gchar *output_str = g_strdup_printf("position %d", position);
2309 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
2310 "Text Caret Moved", output_str);
2317 _notify_table_row_inserted (GObject *obj, gint start_offset,
2321 g_strdup_printf("position %d, num of rows inserted %d!\n",
2322 start_offset, length);
2323 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2324 "Table Row Inserted", output_str);
2329 _notify_table_column_inserted (GObject *obj, gint start_offset,
2333 g_strdup_printf("position %d, num of rows inserted %d!\n",
2334 start_offset, length);
2335 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2336 "Table Column Inserted", output_str);
2341 _notify_table_row_deleted (GObject *obj, gint start_offset,
2344 gchar *output_str = g_strdup_printf("position %d, num of rows inserted %d!\n",
2345 start_offset, length);
2346 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2347 "Table Row Deleted", output_str);
2352 _notify_table_column_deleted (GObject *obj, gint start_offset,
2355 gchar *output_str = g_strdup_printf("position %d, num of rows inserted %d!\n",
2356 start_offset, length);
2357 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2358 "Table Column Deleted", output_str);
2363 _notify_table_row_reordered (GObject *obj)
2365 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2366 "Table Row Reordered", NULL);
2370 _notify_table_column_reordered (GObject *obj)
2372 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2373 "Table Column Reordered", NULL);
2376 /* Object signals */
2379 _notify_object_child_added (GObject *obj, gint index,
2382 gchar *output_str = g_strdup_printf("index %d", index);
2383 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
2384 "Child Added", output_str);
2389 _notify_object_child_removed (GObject *obj, gint index,
2392 gchar *output_str = g_strdup_printf("index %d", index);
2393 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
2394 "Child Removed", output_str);
2399 _notify_object_state_change (GObject *obj, gchar *name, gboolean set)
2401 gchar *output_str = g_strdup_printf("name %s %s set",
2402 name, set ? "is" : "was");
2403 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
2404 "State Change", output_str);
2409 /* Function to print signals */
2412 _print_signal(AtkObject *aobject, FerretSignalType type,
2413 const char *name, const char *info)
2415 TabNumber top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
2423 g_print("SIGNAL:\t%-34s\t%s\n", name, info);
2425 g_print("SIGNAL:\t%-34s\n", name);
2430 if ((type == FERRET_SIGNAL_TEXT) && (!strncmp(name, "Text Caret", 10)))
2432 _speak_caret_event (aobject);
2434 else if (type == FERRET_SIGNAL_TEXT)
2436 last_caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
2440 if (use_magnifier && ATK_IS_TEXT (aobject) &&
2441 (type == FERRET_SIGNAL_TEXT) && (!strncmp(name, "Text Caret", 10)))
2444 gint caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
2445 atk_text_get_character_extents ( ATK_TEXT (aobject), caret_offset, &x, &y, &w, &h, ATK_XY_SCREEN);
2446 _send_to_magnifier (x, y, w, h);
2449 if ((type == FERRET_SIGNAL_TEXT && top_tab == TEXT) ||
2450 (type == FERRET_SIGNAL_TABLE && top_tab == TABLE) ||
2451 (type == FERRET_SIGNAL_OBJECT && top_tab == OBJECT))
2454 g_print("Updating tab\n");
2456 _update(top_tab, aobject);
2460 /* Update functions */
2463 _update (TabNumber top_tab, AtkObject *aobject)
2467 if (top_tab >= OBJECT && top_tab < END_TABS)
2469 _clear_tab(top_tab);
2472 if (top_tab == OBJECT && ATK_IS_OBJECT(aobject))
2474 group_num = _print_object(aobject);
2475 _finished_group(OBJECT, group_num);
2476 group_num = _print_relation(aobject);
2477 _finished_group(OBJECT, group_num);
2478 group_num = _print_state(aobject);
2479 _finished_group(OBJECT, group_num);
2481 if (top_tab == TEXT && ATK_IS_TEXT(aobject))
2483 group_num = _print_text(ATK_TEXT (aobject));
2484 _finished_group(TEXT, group_num);
2485 group_num = _print_text_attributes(ATK_TEXT (aobject));
2486 _finished_group(TEXT, group_num);
2488 if (top_tab == SELECTION && ATK_IS_SELECTION(aobject))
2490 group_num = _print_selection(ATK_SELECTION (aobject));
2491 _finished_group(SELECTION, group_num);
2493 if (top_tab == TABLE && ATK_IS_TABLE(aobject))
2495 group_num = _print_table(ATK_TABLE (aobject));
2496 _finished_group(TABLE, group_num);
2498 if (top_tab == ACTION && ATK_IS_ACTION(aobject))
2500 group_num = _print_action(ATK_ACTION (aobject));
2501 _finished_group(ACTION, group_num);
2503 if (top_tab == COMPONENT && ATK_IS_COMPONENT(aobject))
2505 group_num = _print_component(ATK_COMPONENT(aobject));
2506 _finished_group(COMPONENT, group_num);
2508 if (top_tab == IMAGE && ATK_IS_IMAGE(aobject))
2510 group_num = _print_image(ATK_IMAGE (aobject));
2511 _finished_group(IMAGE, group_num);
2513 if (top_tab == VALUE && ATK_IS_VALUE(aobject))
2515 group_num = _print_value(ATK_VALUE(aobject));
2516 _finished_group(VALUE, group_num);
2521 _update_current_page(GtkNotebook *notebook, gpointer p, guint current_page)
2523 _update(current_page+OBJECT, last_object);
2526 /* Property listeners */
2528 static void _property_change_handler (AtkObject *obj,
2529 AtkPropertyValues *values)
2531 TabNumber top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
2537 * Only process if the property change corrisponds to the current
2540 if (obj != last_object)
2544 g_print("\nProperty change event <%s> for object not in focus\n",
2545 values->property_name);
2553 g_print("\nProperty change event <%s> occurred.\n",
2554 values->property_name);
2558 * Update the top tab if a property changes.
2560 * We may be able to ignore some property changes if they do not
2561 * change anything in ferret.
2564 if (top_tab == OBJECT &&
2565 ((strcmp (values->property_name, "accessible-name") == 0) ||
2566 (strcmp (values->property_name, "accessible-description") == 0) ||
2567 (strcmp (values->property_name, "accessible-parent") == 0) ||
2568 (strcmp (values->property_name, "accessible-value") == 0) ||
2569 (strcmp (values->property_name, "accessible-role") == 0) ||
2570 (strcmp (values->property_name, "accessible-component-layout") == 0) ||
2571 (strcmp (values->property_name, "accessible-component-mdi-zorder") == 0) ||
2572 (strcmp (values->property_name, "accessible-table-caption") == 0) ||
2573 (strcmp (values->property_name,
2574 "accessible-table-column-description") == 0) ||
2575 (strcmp (values->property_name,
2576 "accessible-table-column-header") == 0) ||
2577 (strcmp (values->property_name,
2578 "accessible-table-row-description") == 0) ||
2579 (strcmp (values->property_name,
2580 "accessible-table-row-header") == 0) ||
2581 (strcmp (values->property_name, "accessible-table-summary") == 0)))
2584 g_print("Updating tab\n");
2586 _update(top_tab, last_object);
2588 else if (top_tab == VALUE &&
2589 (strcmp (values->property_name, "accessible-value") == 0))
2592 g_print("Updating tab\n");
2594 _update(top_tab, last_object);
2598 /* Action button callback function */
2600 void _action_cb(GtkWidget *widget, gpointer *userdata)
2602 NameValue *nv = (NameValue *)userdata;
2603 atk_action_do_action(ATK_ACTION(nv->atkobj), nv->action_num);
2606 /* Menu-bar callback functions */
2608 void _toggle_terminal(GtkCheckMenuItem *checkmenuitem,
2611 if (checkmenuitem->active)
2612 display_ascii = TRUE;
2614 display_ascii = FALSE;
2617 void _toggle_no_signals(GtkCheckMenuItem *checkmenuitem,
2620 if (checkmenuitem->active)
2626 void _toggle_magnifier(GtkCheckMenuItem *checkmenuitem,
2629 if (checkmenuitem->active)
2630 use_magnifier = TRUE;
2632 use_magnifier = FALSE;
2635 void _toggle_festival(GtkCheckMenuItem *checkmenuitem,
2638 if (checkmenuitem->active)
2639 use_festival = TRUE;
2641 use_festival = FALSE;
2644 void _toggle_festival_terse(GtkCheckMenuItem *checkmenuitem,
2647 if (checkmenuitem->active)
2659 void _toggle_trackmouse(GtkCheckMenuItem *checkmenuitem,
2662 if (checkmenuitem->active)
2664 mouse_watcher_focus_id =
2665 atk_add_global_event_listener(_mouse_watcher,
2666 "Gtk:GtkWidget:enter_notify_event");
2667 mouse_watcher_button_id =
2668 atk_add_global_event_listener(_button_watcher,
2669 "Gtk:GtkWidget:button_press_event");
2674 if (mouse_watcher_focus_id != -1)
2676 atk_remove_global_event_listener(mouse_watcher_focus_id);
2677 atk_remove_global_event_listener(mouse_watcher_button_id);
2678 track_mouse = FALSE;
2683 void _toggle_trackfocus(GtkCheckMenuItem *checkmenuitem,
2686 if (checkmenuitem->active)
2689 focus_tracker_id = atk_add_focus_tracker (_print_accessible);
2693 g_print ("No longer tracking focus.\n");
2694 track_focus = FALSE;
2695 atk_remove_focus_tracker (focus_tracker_id);