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)
438 n_bytes = write(fd, command_string, strlen(command_string));
439 g_assert (n_bytes == strlen(command_string));
442 static void _speak_caret_event (AtkObject *aobject)
445 gint caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
448 if (abs(caret_offset - last_caret_offset) > 1)
450 text = atk_text_get_text_at_offset (ATK_TEXT (aobject),
452 ATK_TEXT_BOUNDARY_LINE_START,
458 text = atk_text_get_text_before_offset (ATK_TEXT (aobject),
460 ATK_TEXT_BOUNDARY_CHAR,
464 _festival_say (text);
466 last_caret_offset = caret_offset;
470 _greyout_tab (GtkWidget *page_child, gboolean is_sensitive)
474 tab = gtk_notebook_get_tab_label (notebook, page_child);
476 gtk_widget_set_sensitive (GTK_WIDGET (tab), is_sensitive);
480 _refresh_notebook (AtkObject *aobject)
482 if (ATK_IS_OBJECT (aobject))
484 _greyout_tab (nbook_tabs[ACTION]->page, ATK_IS_ACTION(aobject));
485 _greyout_tab (nbook_tabs[COMPONENT]->page, ATK_IS_COMPONENT(aobject));
486 _greyout_tab (nbook_tabs[IMAGE]->page, ATK_IS_IMAGE(aobject));
487 _greyout_tab (nbook_tabs[SELECTION]->page, ATK_IS_SELECTION(aobject));
488 _greyout_tab (nbook_tabs[TABLE]->page, ATK_IS_TABLE(aobject));
489 _greyout_tab (nbook_tabs[TEXT]->page, ATK_IS_TEXT(aobject));
490 _greyout_tab (nbook_tabs[VALUE]->page, ATK_IS_VALUE(aobject));
494 static void _print_accessible (AtkObject *aobject)
498 if (_object_is_ours(aobject))
501 g_print("\nFocus entered the ferret output window!\n");
505 _refresh_notebook(aobject);
508 g_print("\nFocus change\n");
510 /* Do not attach signal handlers if the user has asked not to */
512 _update_handlers(aobject);
514 last_object = aobject; /* _update_handler normally does this */
516 top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
517 _update(top_tab, aobject);
524 if (ATK_IS_TEXT (aobject))
529 len = atk_text_get_character_count (ATK_TEXT (aobject));
530 atk_text_get_character_extents (ATK_TEXT (aobject), 0,
535 atk_text_get_character_extents (ATK_TEXT (aobject), len-1,
540 w = MAX (x0+w0, xN+wN) - x;
541 h = MAX (y0+h0, yN+hN) - y;
549 else if (ATK_IS_COMPONENT (aobject))
551 atk_component_get_extents (ATK_COMPONENT(aobject),
555 if (w > -1) _send_to_magnifier (x, y, w, h);
560 _object_is_ours (AtkObject *aobject)
562 /* determine whether this object is parented by our own accessible... */
564 AtkObject *toplevel = aobject;
566 while (atk_object_get_role(aobject) != ATK_ROLE_FRAME)
568 aobject = atk_object_get_parent (aobject);
569 if (aobject == NULL) break;
574 * Some widgets do not have an ATK_ROLE_FRAME at the top,
579 if (GTK_ACCESSIBLE(toplevel)->widget == mainWindow)
589 ferret_get_name_from_container (AtkObject *aobject)
592 gint n = atk_object_get_n_accessible_children (aobject);
595 while (!s && (i < n))
598 child = atk_object_ref_accessible_child (aobject, i);
599 if (ATK_IS_TEXT (child))
601 gint count = atk_text_get_character_count (ATK_TEXT (child));
602 s = atk_text_get_text (ATK_TEXT (child),
606 g_object_unref (child);
618 _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 if (GTK_IS_ACCESSIBLE (aobject) &&
660 GTK_IS_WIDGET (GTK_ACCESSIBLE (aobject)->widget))
662 _print_key_value(tab_n, group_num, "Widget name",
663 (gpointer)gtk_widget_get_name(GTK_ACCESSIBLE (aobject)->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");
1669 gtk_window_set_policy (GTK_WINDOW(window), TRUE, TRUE, FALSE);
1671 g_signal_connect (GTK_OBJECT (window), "destroy",
1672 G_CALLBACK (gtk_widget_destroyed),
1675 gtk_window_set_title (GTK_WINDOW (window), "GTK+ Ferret Output");
1676 gtk_window_set_default_size (GTK_WINDOW (window), 333, 550);
1677 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1679 vbox1 = gtk_vbox_new (FALSE, 0);
1680 gtk_container_add (GTK_CONTAINER (window), vbox1);
1681 gtk_widget_show (vbox1);
1683 menubar = gtk_menu_bar_new ();
1684 gtk_box_pack_start (GTK_BOX (vbox1), menubar, FALSE, TRUE, 0);
1685 gtk_widget_show (menubar);
1686 menutop = gtk_menu_item_new_with_label("Menu");
1687 gtk_menu_bar_append(GTK_MENU_BAR(menubar), menutop);
1688 gtk_widget_show (menutop);
1689 menu = gtk_menu_new();
1690 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menutop), menu);
1691 gtk_widget_show (menu);
1693 _add_menu(&menu, &menuitem_trackmouse, "Track Mouse", track_mouse,
1694 G_CALLBACK(_toggle_trackmouse));
1695 _add_menu(&menu, &menuitem_trackfocus, "Track Focus", track_focus,
1696 G_CALLBACK(_toggle_trackfocus));
1697 _add_menu(&menu, &menuitem_magnifier, "Magnifier", use_magnifier,
1698 G_CALLBACK(_toggle_magnifier));
1699 _add_menu(&menu, &menuitem_festival, "Festival", use_festival,
1700 G_CALLBACK(_toggle_festival));
1701 _add_menu(&menu, &menuitem_festival_terse, "Festival Terse",
1702 (!say_role && !say_accel),
1703 G_CALLBACK(_toggle_festival_terse));
1704 _add_menu(&menu, &menuitem_terminal, "Terminal Output", display_ascii,
1705 G_CALLBACK(_toggle_terminal));
1706 _add_menu(&menu, &menuitem_no_signals, "No ATK Signals", no_signals,
1707 G_CALLBACK(_toggle_no_signals));
1709 _create_notebook ();
1710 gtk_container_add (GTK_CONTAINER (vbox1), GTK_WIDGET (notebook));
1711 gtk_widget_show (GTK_WIDGET (notebook));
1713 if (!GTK_WIDGET_VISIBLE (window))
1714 gtk_widget_show (window);
1716 mainWindow = GTK_WIDGET (window);
1720 _add_menu(GtkWidget ** menu, GtkWidget ** menuitem, gchar * name,
1721 gboolean init_value, GCallback func)
1723 *menuitem = gtk_check_menu_item_new_with_label(name);
1724 gtk_check_menu_item_set_active(
1725 GTK_CHECK_MENU_ITEM(*menuitem), init_value);
1726 gtk_menu_shell_append (GTK_MENU_SHELL (*menu), *menuitem);
1727 gtk_widget_show(*menuitem);
1728 g_signal_connect(GTK_OBJECT(*menuitem), "toggled", func, NULL);
1732 gtk_module_init(gint argc, char* argv[])
1734 if (g_getenv ("FERRET_ASCII"))
1735 display_ascii = TRUE;
1737 if (g_getenv ("FERRET_NOSIGNALS"))
1741 g_print("GTK ferret Module loaded\n");
1743 if (g_getenv("FERRET_MAGNIFIER"))
1744 use_magnifier = TRUE;
1746 if (g_getenv ("FERRET_FESTIVAL"))
1747 use_festival = TRUE;
1749 if (g_getenv ("FERRET_MOUSETRACK"))
1752 if (g_getenv ("FERRET_TERSE"))
1762 _create_event_watcher();
1768 _clear_tab(TabNumber tab_n)
1770 GList *group_list, *nv_list;
1775 tab = nbook_tabs[tab_n];
1777 for (group_list = tab->groups; group_list; group_list = group_list->next)
1779 group = (GroupInfo *) group_list->data;
1781 if (group->is_scrolled)
1782 gtk_widget_hide(GTK_WIDGET(group->scroll_outer_frame));
1784 gtk_widget_hide(GTK_WIDGET(group->frame));
1785 gtk_widget_hide(GTK_WIDGET(group->group_vbox));
1787 for (nv_list = group->name_value; nv_list; nv_list = nv_list->next)
1789 nv = (NameValue *) nv_list->data;
1791 gtk_widget_hide(GTK_WIDGET(nv->column1));
1792 gtk_widget_hide(GTK_WIDGET(nv->column2));
1793 gtk_widget_hide(GTK_WIDGET(nv->label));
1798 gtk_widget_hide(GTK_WIDGET(nv->string));
1801 gtk_widget_hide(GTK_WIDGET(nv->boolean));
1804 gtk_widget_hide(GTK_WIDGET(nv->text));
1807 gtk_widget_hide(GTK_WIDGET(nv->button));
1810 gtk_widget_hide(GTK_WIDGET(nv->hbox));
1812 /* Disconnect signal handler if any */
1813 if (nv->signal_id != -1)
1814 g_signal_handler_disconnect(nv->button, nv->signal_id);
1822 _print_groupname(TabNumber tab_n, GroupId group_id,
1823 const char *groupname)
1826 GroupInfo *the_group;
1830 g_print("\n<%s>\n", groupname);
1832 tab = nbook_tabs[tab_n];
1833 the_group = _get_group(tab, group_id, groupname);
1834 rc = g_list_index(tab->groups, the_group);
1839 _get_group(TabInfo *tab, GroupId group_id, const gchar *groupname)
1841 GroupInfo *group = NULL;
1842 gboolean found = FALSE;
1845 for (group_list = tab->groups; group_list; group_list = group_list->next)
1847 group = (GroupInfo *) group_list->data;
1848 if (group_id == group->group_id)
1857 /* build a new one */
1858 group = (GroupInfo *)g_new0(GroupInfo, 1);
1859 group->group_id = group_id;
1860 _get_group_scrolled(group);
1862 if (group->is_scrolled)
1864 group->frame = gtk_scrolled_window_new (NULL, NULL);
1865 gtk_widget_set_size_request (GTK_WIDGET (group->frame), -2,
1866 group->default_height);
1867 group->scroll_outer_frame = GTK_FRAME(gtk_frame_new(groupname));
1868 gtk_container_add(GTK_CONTAINER(group->scroll_outer_frame),
1873 group->frame = gtk_frame_new(groupname);
1876 gtk_container_set_border_width(GTK_CONTAINER(group->frame), 10);
1878 group->name = g_strdup(groupname);
1879 group->group_vbox = GTK_VBOX(gtk_vbox_new(FALSE, 10));
1881 if (group->is_scrolled)
1883 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (group->frame),
1884 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1885 gtk_scrolled_window_add_with_viewport(
1886 GTK_SCROLLED_WINDOW(group->frame),
1887 GTK_WIDGET(group->group_vbox));
1891 gtk_container_add(GTK_CONTAINER(group->frame),
1892 GTK_WIDGET(group->group_vbox));
1895 tab->groups = g_list_append (tab->groups, group);
1897 if (group->is_scrolled)
1899 gtk_box_pack_start (GTK_BOX (tab->main_box),
1900 GTK_WIDGET (group->scroll_outer_frame),
1905 gtk_box_pack_start (GTK_BOX (tab->main_box),
1906 GTK_WIDGET (group->frame),
1915 _get_group_scrolled(GroupInfo *group)
1917 if (group->group_id == OBJECT_INTERFACE)
1919 group->is_scrolled = FALSE;
1921 else if (group->group_id == RELATION_INTERFACE)
1923 group->is_scrolled = TRUE;
1924 group->default_height = 50;
1926 else if (group->group_id == STATE_INTERFACE)
1928 group->is_scrolled = TRUE;
1929 group->default_height = 100;
1931 else if (group->group_id == ACTION_INTERFACE)
1933 group->is_scrolled = TRUE;
1934 group->default_height = 200;
1936 else if (group->group_id == TEXT_ATTRIBUTES)
1938 group->is_scrolled = TRUE;
1939 group->default_height = 70;
1943 group->is_scrolled = FALSE;
1948 _get_name_value(GroupInfo *group, const gchar *label,
1949 gpointer value_ptr, ValueType type)
1951 NameValue *name_value = NULL;
1954 gboolean found = FALSE;
1955 static char *empty_string = "";
1959 label = empty_string;
1962 for (nv_list = group->name_value; nv_list; nv_list = nv_list->next)
1964 name_value = (NameValue *) nv_list->data;
1965 if (!name_value->active)
1974 name_value = (NameValue *)g_new0(NameValue, 1);
1975 name_value->column1 = GTK_HBOX(gtk_hbox_new(FALSE, 10));
1976 name_value->column2 = GTK_HBOX(gtk_hbox_new(FALSE, 10));
1977 name_value->hbox = GTK_HBOX(gtk_hbox_new(FALSE, 5));
1978 name_value->label = GTK_LABEL(gtk_label_new(label));
1979 name_value->string = gtk_label_new (NULL);
1980 name_value->boolean = gtk_check_button_new ();
1981 name_value->text = gtk_entry_new_with_max_length (1000);
1982 name_value->button = GTK_BUTTON(gtk_button_new ());
1984 gtk_box_pack_end(GTK_BOX(name_value->column1),
1985 GTK_WIDGET(name_value->label), FALSE, FALSE, 10);
1990 gtk_label_set_text(GTK_LABEL(name_value->string),
1991 (gchar *) value_ptr);
1992 gtk_box_pack_start(GTK_BOX(name_value->column2),
1993 GTK_WIDGET(name_value->string), FALSE, FALSE, 10);
1996 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(name_value->boolean),
1997 *((gboolean *)value_ptr));
1998 gtk_widget_set_sensitive(name_value->boolean, FALSE);
1999 gtk_box_pack_start(GTK_BOX(name_value->column2),
2000 GTK_WIDGET(name_value->boolean), FALSE, FALSE, 10);
2003 gtk_entry_set_text (GTK_ENTRY (name_value->text),
2004 (gchar *)value_ptr);
2005 gtk_box_pack_start(GTK_BOX(name_value->column2),
2006 GTK_WIDGET(name_value->text), FALSE, FALSE, 10);
2008 value = &(name_value->button_gval);
2009 memset (value, 0, sizeof (GValue));
2010 g_value_init (value, G_TYPE_STRING);
2011 g_value_set_string (value, (gchar *)value_ptr);
2012 g_object_set_property(G_OBJECT(name_value->button),
2014 gtk_box_pack_start(GTK_BOX(name_value->column2),
2015 GTK_WIDGET(name_value->button), FALSE, FALSE, 10);
2019 gtk_box_pack_start (GTK_BOX (name_value->hbox),
2020 GTK_WIDGET (name_value->column1),
2022 gtk_box_pack_start (GTK_BOX (name_value->hbox),
2023 GTK_WIDGET (name_value->column2),
2025 gtk_container_add(GTK_CONTAINER(group->group_vbox),
2026 GTK_WIDGET(name_value->hbox));
2027 group->name_value = g_list_append (group->name_value, name_value);
2031 gtk_label_set_text(GTK_LABEL(name_value->label), label);
2035 gtk_label_set_text(GTK_LABEL(name_value->string),
2036 (gchar *) value_ptr);
2039 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(name_value->boolean),
2040 *((gboolean *)value_ptr));
2041 gtk_widget_set_sensitive(name_value->boolean, FALSE);
2044 gtk_entry_set_text (GTK_ENTRY (name_value->text),
2045 (gchar *) value_ptr);
2048 value = &(name_value->button_gval);
2049 memset (value, 0, sizeof (GValue));
2050 g_value_init (value, G_TYPE_STRING);
2051 g_value_set_string (value, (gchar *)value_ptr);
2052 g_object_set_property(G_OBJECT(name_value->button),
2058 name_value->active = TRUE;
2059 name_value->type = type;
2060 name_value->signal_id = -1;
2062 gtk_widget_show(GTK_WIDGET(name_value->label));
2067 gtk_widget_show(GTK_WIDGET(name_value->string));
2070 gtk_widget_show(GTK_WIDGET(name_value->boolean));
2073 gtk_widget_show(GTK_WIDGET(name_value->text));
2076 gtk_widget_show(GTK_WIDGET(name_value->button));
2080 gtk_widget_show(GTK_WIDGET(name_value->column1));
2081 gtk_widget_show(GTK_WIDGET(name_value->column2));
2082 gtk_widget_show(GTK_WIDGET(name_value->hbox));
2083 gtk_widget_show(GTK_WIDGET(group->group_vbox));
2089 _print_key_value(TabNumber tab_n, gint group_number,
2090 const char *label, gpointer value, ValueType type)
2093 GroupInfo *the_group;
2097 if (type == VALUE_BOOLEAN)
2099 if (*((gboolean *)value))
2100 g_print("\t%-30s\tTRUE\n", label);
2102 g_print("\t%-30s\tFALSE\n", label);
2106 g_print("\t%-30s\t%s\n", label,
2107 value ? (gchar *)value : "NULL");
2111 tab = nbook_tabs[tab_n];
2112 the_group = (GroupInfo *)g_list_nth_data(tab->groups, group_number);
2113 return _get_name_value(the_group, label, (gpointer)value, type);
2117 _finished_group(TabNumber tab_no, gint group_number)
2120 GroupInfo *the_group;
2122 tab = nbook_tabs[tab_no];
2124 the_group = (GroupInfo *)g_list_nth_data(tab->groups, group_number);
2126 if (the_group->is_scrolled)
2127 gtk_widget_show(GTK_WIDGET(the_group->scroll_outer_frame));
2129 gtk_widget_show(GTK_WIDGET(the_group->frame));
2130 gtk_widget_show(GTK_WIDGET(the_group->group_vbox));
2131 gtk_widget_show(GTK_WIDGET(tab->main_box));
2134 /* Signal handlers */
2136 static gulong child_added_id = 0;
2137 static gulong child_removed_id = 0;
2138 static gulong state_change_id = 0;
2140 static gulong text_caret_handler_id = 0;
2141 static gulong text_inserted_id = 0;
2142 static gulong text_deleted_id = 0;
2144 static gulong table_row_inserted_id = 0;
2145 static gulong table_column_inserted_id = 0;
2146 static gulong table_row_deleted_id = 0;
2147 static gulong table_column_deleted_id = 0;
2148 static gulong table_row_reordered_id = 0;
2149 static gulong table_column_reordered_id = 0;
2151 static gulong property_id = 0;
2154 _update_handlers(AtkObject *obj)
2156 /* Remove signal handlers from object that had focus before */
2158 if (last_object != NULL && G_TYPE_CHECK_INSTANCE(last_object))
2160 if (child_added_id != 0)
2161 g_signal_handler_disconnect(last_object, child_added_id);
2162 if (child_removed_id != 0)
2163 g_signal_handler_disconnect(last_object, child_removed_id);
2164 if (state_change_id != 0)
2165 g_signal_handler_disconnect(last_object, state_change_id);
2167 if (text_caret_handler_id != 0)
2168 g_signal_handler_disconnect(last_object, text_caret_handler_id);
2169 if (text_inserted_id != 0)
2170 g_signal_handler_disconnect(last_object, text_inserted_id);
2171 if (text_deleted_id != 0)
2172 g_signal_handler_disconnect(last_object, text_deleted_id);
2174 if (table_row_inserted_id != 0)
2175 g_signal_handler_disconnect(last_object, table_row_inserted_id);
2176 if (table_column_inserted_id != 0)
2177 g_signal_handler_disconnect(last_object, table_column_inserted_id);
2178 if (table_row_deleted_id != 0)
2179 g_signal_handler_disconnect(last_object, table_row_deleted_id);
2180 if (table_column_deleted_id != 0)
2181 g_signal_handler_disconnect(last_object, table_column_deleted_id);
2182 if (table_row_reordered_id != 0)
2183 g_signal_handler_disconnect(last_object, table_row_reordered_id);
2184 if (table_column_reordered_id != 0)
2185 g_signal_handler_disconnect(last_object, table_column_reordered_id);
2186 if (property_id != 0)
2187 g_signal_handler_disconnect(last_object, property_id);
2189 g_object_unref(last_object);
2195 child_removed_id = 0;
2196 text_caret_handler_id = 0;
2197 text_inserted_id = 0;
2198 text_deleted_id = 0;
2199 table_row_inserted_id = 0;
2200 table_column_inserted_id = 0;
2201 table_row_deleted_id = 0;
2202 table_column_deleted_id = 0;
2203 table_row_reordered_id = 0;
2204 table_column_reordered_id = 0;
2207 if (!G_TYPE_CHECK_INSTANCE(obj))
2213 /* Add signal handlers to object that now has focus. */
2215 if (ATK_IS_OBJECT(obj))
2217 child_added_id = g_signal_connect_closure (obj,
2218 "children_changed::add",
2219 g_cclosure_new (G_CALLBACK (_notify_object_child_added),
2220 NULL, NULL), FALSE);
2222 child_removed_id = g_signal_connect_closure (obj,
2223 "children_changed::remove",
2224 g_cclosure_new (G_CALLBACK (_notify_object_child_removed),
2225 NULL, NULL), FALSE);
2227 state_change_id = g_signal_connect_closure (obj,
2229 g_cclosure_new (G_CALLBACK (_notify_object_state_change),
2230 NULL, NULL), FALSE);
2233 if (ATK_IS_TEXT(obj))
2235 text_caret_handler_id = g_signal_connect_closure_by_id (obj,
2236 g_signal_lookup ("text_caret_moved", G_OBJECT_TYPE (obj)),
2237 0, g_cclosure_new (G_CALLBACK (_notify_caret_handler),
2238 NULL, NULL), FALSE);
2239 text_inserted_id = g_signal_connect_closure (obj,
2240 "text_changed::insert",
2241 g_cclosure_new (G_CALLBACK (_notify_text_insert_handler),
2242 NULL, NULL), FALSE);
2243 text_deleted_id = g_signal_connect_closure (obj,
2244 "text_changed::delete",
2245 g_cclosure_new (G_CALLBACK (_notify_text_delete_handler),
2246 NULL, NULL), FALSE);
2249 if (ATK_IS_TABLE(obj))
2251 table_row_inserted_id = g_signal_connect_closure_by_id (obj,
2252 g_signal_lookup ("row_inserted", G_OBJECT_TYPE (obj)),
2253 0, g_cclosure_new (G_CALLBACK (_notify_table_row_inserted),
2254 NULL, NULL), FALSE);
2255 table_column_inserted_id = g_signal_connect_closure_by_id (obj,
2256 g_signal_lookup ("column_inserted", G_OBJECT_TYPE (obj)),
2257 0, g_cclosure_new (G_CALLBACK (_notify_table_column_inserted),
2258 NULL, NULL), FALSE);
2259 table_row_deleted_id = g_signal_connect_closure_by_id (obj,
2260 g_signal_lookup ("row_deleted", G_OBJECT_TYPE (obj)),
2261 0, g_cclosure_new (G_CALLBACK (_notify_table_row_deleted),
2262 NULL, NULL), FALSE);
2263 table_column_deleted_id = g_signal_connect_closure_by_id (obj,
2264 g_signal_lookup ("column_deleted", G_OBJECT_TYPE (obj)),
2265 0, g_cclosure_new (G_CALLBACK (_notify_table_column_deleted),
2266 NULL, NULL), FALSE);
2267 table_row_reordered_id = g_signal_connect_closure_by_id (obj,
2268 g_signal_lookup ("row_reordered", G_OBJECT_TYPE (obj)),
2269 0, g_cclosure_new (G_CALLBACK (_notify_table_row_reordered),
2270 NULL, NULL), FALSE);
2271 table_column_reordered_id = g_signal_connect_closure_by_id (obj,
2272 g_signal_lookup ("column_reordered", G_OBJECT_TYPE (obj)),
2273 0, g_cclosure_new (G_CALLBACK (_notify_table_column_reordered),
2274 NULL, NULL), FALSE);
2277 property_id = g_signal_connect_closure_by_id (obj,
2278 g_signal_lookup ("property_change", G_OBJECT_TYPE (obj)),
2279 0, g_cclosure_new (G_CALLBACK (_property_change_handler),
2287 _notify_text_insert_handler (GObject *obj, int position, int offset)
2289 gchar *text = atk_text_get_text (ATK_TEXT (obj), position, position + offset);
2290 gchar *output_str = g_strdup_printf("position %d, length %d text: %s",
2291 position, offset, text ? text: "<NULL>");
2292 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
2293 "Text Insert", output_str);
2298 _notify_text_delete_handler (GObject *obj, int position, int offset)
2300 gchar *text = atk_text_get_text (ATK_TEXT (obj), position, position + offset);
2301 gchar *output_str = g_strdup_printf("position %d, length %d text: %s",
2302 position, offset, text ? text: "<NULL>");
2303 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
2304 "Text Delete", output_str);
2309 _notify_caret_handler (GObject *obj, int position)
2311 gchar *output_str = g_strdup_printf("position %d", position);
2312 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TEXT,
2313 "Text Caret Moved", output_str);
2320 _notify_table_row_inserted (GObject *obj, gint start_offset,
2324 g_strdup_printf("position %d, num of rows inserted %d!\n",
2325 start_offset, length);
2326 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2327 "Table Row Inserted", output_str);
2332 _notify_table_column_inserted (GObject *obj, gint start_offset,
2336 g_strdup_printf("position %d, num of rows inserted %d!\n",
2337 start_offset, length);
2338 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2339 "Table Column Inserted", output_str);
2344 _notify_table_row_deleted (GObject *obj, gint start_offset,
2347 gchar *output_str = g_strdup_printf("position %d, num of rows inserted %d!\n",
2348 start_offset, length);
2349 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2350 "Table Row Deleted", output_str);
2355 _notify_table_column_deleted (GObject *obj, gint start_offset,
2358 gchar *output_str = g_strdup_printf("position %d, num of rows inserted %d!\n",
2359 start_offset, length);
2360 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2361 "Table Column Deleted", output_str);
2366 _notify_table_row_reordered (GObject *obj)
2368 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2369 "Table Row Reordered", NULL);
2373 _notify_table_column_reordered (GObject *obj)
2375 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_TABLE,
2376 "Table Column Reordered", NULL);
2379 /* Object signals */
2382 _notify_object_child_added (GObject *obj, gint index,
2385 gchar *output_str = g_strdup_printf("index %d", index);
2386 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
2387 "Child Added", output_str);
2392 _notify_object_child_removed (GObject *obj, gint index,
2395 gchar *output_str = g_strdup_printf("index %d", index);
2396 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
2397 "Child Removed", output_str);
2402 _notify_object_state_change (GObject *obj, gchar *name, gboolean set)
2404 gchar *output_str = g_strdup_printf("name %s %s set",
2405 name, set ? "is" : "was");
2406 _print_signal(ATK_OBJECT(obj), FERRET_SIGNAL_OBJECT,
2407 "State Change", output_str);
2412 /* Function to print signals */
2415 _print_signal(AtkObject *aobject, FerretSignalType type,
2416 const char *name, const char *info)
2418 TabNumber top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
2426 g_print("SIGNAL:\t%-34s\t%s\n", name, info);
2428 g_print("SIGNAL:\t%-34s\n", name);
2433 if ((type == FERRET_SIGNAL_TEXT) && (!strncmp(name, "Text Caret", 10)))
2435 _speak_caret_event (aobject);
2437 else if (type == FERRET_SIGNAL_TEXT)
2439 last_caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
2443 if (use_magnifier && ATK_IS_TEXT (aobject) &&
2444 (type == FERRET_SIGNAL_TEXT) && (!strncmp(name, "Text Caret", 10)))
2447 gint caret_offset = atk_text_get_caret_offset (ATK_TEXT (aobject));
2448 atk_text_get_character_extents ( ATK_TEXT (aobject), caret_offset, &x, &y, &w, &h, ATK_XY_SCREEN);
2449 _send_to_magnifier (x, y, w, h);
2452 if ((type == FERRET_SIGNAL_TEXT && top_tab == TEXT) ||
2453 (type == FERRET_SIGNAL_TABLE && top_tab == TABLE) ||
2454 (type == FERRET_SIGNAL_OBJECT && top_tab == OBJECT))
2457 g_print("Updating tab\n");
2459 _update(top_tab, aobject);
2463 /* Update functions */
2466 _update (TabNumber top_tab, AtkObject *aobject)
2470 if (top_tab >= OBJECT && top_tab < END_TABS)
2472 _clear_tab(top_tab);
2475 if (top_tab == OBJECT && ATK_IS_OBJECT(aobject))
2477 group_num = _print_object(aobject);
2478 _finished_group(OBJECT, group_num);
2479 group_num = _print_relation(aobject);
2480 _finished_group(OBJECT, group_num);
2481 group_num = _print_state(aobject);
2482 _finished_group(OBJECT, group_num);
2484 if (top_tab == TEXT && ATK_IS_TEXT(aobject))
2486 group_num = _print_text(ATK_TEXT (aobject));
2487 _finished_group(TEXT, group_num);
2488 group_num = _print_text_attributes(ATK_TEXT (aobject));
2489 _finished_group(TEXT, group_num);
2491 if (top_tab == SELECTION && ATK_IS_SELECTION(aobject))
2493 group_num = _print_selection(ATK_SELECTION (aobject));
2494 _finished_group(SELECTION, group_num);
2496 if (top_tab == TABLE && ATK_IS_TABLE(aobject))
2498 group_num = _print_table(ATK_TABLE (aobject));
2499 _finished_group(TABLE, group_num);
2501 if (top_tab == ACTION && ATK_IS_ACTION(aobject))
2503 group_num = _print_action(ATK_ACTION (aobject));
2504 _finished_group(ACTION, group_num);
2506 if (top_tab == COMPONENT && ATK_IS_COMPONENT(aobject))
2508 group_num = _print_component(ATK_COMPONENT(aobject));
2509 _finished_group(COMPONENT, group_num);
2511 if (top_tab == IMAGE && ATK_IS_IMAGE(aobject))
2513 group_num = _print_image(ATK_IMAGE (aobject));
2514 _finished_group(IMAGE, group_num);
2516 if (top_tab == VALUE && ATK_IS_VALUE(aobject))
2518 group_num = _print_value(ATK_VALUE(aobject));
2519 _finished_group(VALUE, group_num);
2524 _update_current_page(GtkNotebook *notebook, gpointer p, guint current_page)
2526 _update(current_page+OBJECT, last_object);
2529 /* Property listeners */
2531 static void _property_change_handler (AtkObject *obj,
2532 AtkPropertyValues *values)
2534 TabNumber top_tab = gtk_notebook_get_current_page (notebook) + OBJECT;
2540 * Only process if the property change corrisponds to the current
2543 if (obj != last_object)
2547 g_print("\nProperty change event <%s> for object not in focus\n",
2548 values->property_name);
2556 g_print("\nProperty change event <%s> occurred.\n",
2557 values->property_name);
2561 * Update the top tab if a property changes.
2563 * We may be able to ignore some property changes if they do not
2564 * change anything in ferret.
2567 if (top_tab == OBJECT &&
2568 ((strcmp (values->property_name, "accessible-name") == 0) ||
2569 (strcmp (values->property_name, "accessible-description") == 0) ||
2570 (strcmp (values->property_name, "accessible-parent") == 0) ||
2571 (strcmp (values->property_name, "accessible-value") == 0) ||
2572 (strcmp (values->property_name, "accessible-role") == 0) ||
2573 (strcmp (values->property_name, "accessible-component-layout") == 0) ||
2574 (strcmp (values->property_name, "accessible-component-mdi-zorder") == 0) ||
2575 (strcmp (values->property_name, "accessible-table-caption") == 0) ||
2576 (strcmp (values->property_name,
2577 "accessible-table-column-description") == 0) ||
2578 (strcmp (values->property_name,
2579 "accessible-table-column-header") == 0) ||
2580 (strcmp (values->property_name,
2581 "accessible-table-row-description") == 0) ||
2582 (strcmp (values->property_name,
2583 "accessible-table-row-header") == 0) ||
2584 (strcmp (values->property_name, "accessible-table-summary") == 0)))
2587 g_print("Updating tab\n");
2589 _update(top_tab, last_object);
2591 else if (top_tab == VALUE &&
2592 (strcmp (values->property_name, "accessible-value") == 0))
2595 g_print("Updating tab\n");
2597 _update(top_tab, last_object);
2601 /* Action button callback function */
2603 void _action_cb(GtkWidget *widget, gpointer *userdata)
2605 NameValue *nv = (NameValue *)userdata;
2606 atk_action_do_action(ATK_ACTION(nv->atkobj), nv->action_num);
2609 /* Menu-bar callback functions */
2611 void _toggle_terminal(GtkCheckMenuItem *checkmenuitem,
2614 if (checkmenuitem->active)
2615 display_ascii = TRUE;
2617 display_ascii = FALSE;
2620 void _toggle_no_signals(GtkCheckMenuItem *checkmenuitem,
2623 if (checkmenuitem->active)
2629 void _toggle_magnifier(GtkCheckMenuItem *checkmenuitem,
2632 if (checkmenuitem->active)
2633 use_magnifier = TRUE;
2635 use_magnifier = FALSE;
2638 void _toggle_festival(GtkCheckMenuItem *checkmenuitem,
2641 if (checkmenuitem->active)
2642 use_festival = TRUE;
2644 use_festival = FALSE;
2647 void _toggle_festival_terse(GtkCheckMenuItem *checkmenuitem,
2650 if (checkmenuitem->active)
2662 void _toggle_trackmouse(GtkCheckMenuItem *checkmenuitem,
2665 if (checkmenuitem->active)
2667 mouse_watcher_focus_id =
2668 atk_add_global_event_listener(_mouse_watcher,
2669 "Gtk:GtkWidget:enter_notify_event");
2670 mouse_watcher_button_id =
2671 atk_add_global_event_listener(_button_watcher,
2672 "Gtk:GtkWidget:button_press_event");
2677 if (mouse_watcher_focus_id != -1)
2679 atk_remove_global_event_listener(mouse_watcher_focus_id);
2680 atk_remove_global_event_listener(mouse_watcher_button_id);
2681 track_mouse = FALSE;
2686 void _toggle_trackfocus(GtkCheckMenuItem *checkmenuitem,
2689 if (checkmenuitem->active)
2692 focus_tracker_id = atk_add_focus_tracker (_print_accessible);
2696 g_print ("No longer tracking focus.\n");
2697 track_focus = FALSE;
2698 atk_remove_focus_tracker (focus_tracker_id);