2001-12-10 Michael Meeks <michael@ximian.com>
[platform/core/uifw/at-spi2-atk.git] / test / accessx-gui.c
1 /*
2  * AT-SPI - Assistive Technology Service Provider Interface
3  * (Gnome Accessibility Project; http://developer.gnome.org/projects/gap)
4  *
5  * Copyright 2001 Sun Microsystems Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <gtk/gtk.h>
27 #include <gdk/gdkx.h>
28 #include <X11/XKBlib.h> /* AccessX control defs */
29 #include "spi.h"
30
31 #define N_CONTROLS 8
32
33 static XkbDescPtr xkb;
34
35 typedef struct {
36         unsigned long  mask;
37         short int     *val;
38         char          *label;
39         char          *val_label;
40 } AccessXControlStruct;
41
42 static void
43 gui_exit(GtkButton *notused, void *alsonotused)
44 {
45   gtk_exit(0);
46 }
47
48 static void
49 toggle_xkb_control (GtkButton *toggle_button, AccessXControlStruct *control_struct)
50 {
51   gboolean is_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle_button));
52   XkbChangeEnabledControls (GDK_DISPLAY(), XkbUseCoreKbd, control_struct->mask,
53                             is_active ? control_struct->mask : 0);
54 }
55
56 static void
57 toggle_xkb_notify_control (GtkButton *toggle_button, AccessXControlStruct *control_struct)
58 {
59   gboolean is_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle_button));
60   unsigned short mask, always_off_mask;
61   XkbChangeEnabledControls (GDK_DISPLAY(), XkbUseCoreKbd, XkbAccessXFeedbackMask | XkbAudibleBellMask,
62                             XkbAccessXFeedbackMask | XkbAudibleBellMask);
63   
64   mask = XkbAX_TwoKeysMask | XkbAX_LatchToLockMask | XkbAX_DumbBellFBMask;
65   always_off_mask = XkbAX_SKPressFBMask | XkbAX_SKReleaseFBMask;
66
67   if (is_active)
68           xkb->ctrls->ax_options |= (control_struct->mask  |  mask);
69   else
70           xkb->ctrls->ax_options &= (~control_struct->mask);
71
72   xkb->ctrls->ax_options &= ~always_off_mask;
73   
74   XkbSetControls (GDK_DISPLAY(), XkbAccessXFeedbackMask, xkb);
75 }
76
77 static void
78 toggle_accessx (GtkButton *toggle_button, void *unused)
79 {
80   gboolean is_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle_button));
81   XkbChangeEnabledControls (GDK_DISPLAY(), XkbUseCoreKbd, XkbAllBooleanCtrlsMask,
82     (is_active) ? xkb->ctrls->enabled_ctrls : 0);
83 /*if (is_active/) XkbSetControls (GDK_DISPLAY(), XkbAllBooleanCtrlsMask, xkb);*/
84 }
85
86 static void
87 set_accessx_control_value (GtkRange *range_control, AccessXControlStruct *control_struct)
88 {
89   *(control_struct->val) = (short int) gtk_range_get_value (range_control);
90   XkbSetControls (GDK_DISPLAY(), control_struct->mask, xkb);
91 }
92
93 static gboolean
94 init_xkb ()
95 {
96   int opcode, xkb_event_code, error, result, major, minor;
97   Status status;
98   result = XkbQueryExtension (GDK_DISPLAY(), &opcode, &xkb_event_code, &error, &major, &minor);
99   if (result != True) return False;
100   
101   xkb = XkbGetMap(GDK_DISPLAY(), 0, XkbUseCoreKbd);
102   if ((int)xkb == BadAlloc || xkb == NULL)
103   {
104       return False; 
105   }
106   else
107   {
108       status = XkbGetControls(GDK_DISPLAY(), XkbAllControlsMask, xkb);
109       if (status != Success)
110       {
111          XkbFreeKeyboard(xkb, XkbAllControlsMask, True);
112          return False;
113       }
114       else
115       {
116         if (!xkb->ctrls)
117         {
118           XkbFreeKeyboard(xkb, XkbAllControlsMask, True);
119           return False;
120         }
121       }
122   }
123
124   return True;      
125 }
126
127 static AccessXControlStruct *
128 control_struct_new (unsigned int mask,
129                     short int *val_ptr,
130                     char *label,
131                     char *val_label)
132 {
133   AccessXControlStruct *control = g_new0 (AccessXControlStruct, 1);
134   control->mask = mask;
135   control->val = val_ptr;
136   control->label = label;
137   control->val_label = val_label;
138   return control;
139 }
140
141 static GtkWidget*
142 basic_toggles_box ()
143 {
144   GtkWidget *hbox, *outer_vbox, *vbox, *label, *button, *range, *frame;
145   GtkAdjustment *adjustment;
146   AccessXControlStruct *control;
147   
148   outer_vbox = gtk_widget_new (GTK_TYPE_VBOX,
149                          "GtkWidget::visible", TRUE,
150                          NULL);
151   
152   hbox = gtk_widget_new (GTK_TYPE_HBOX,
153                          "GtkWidget::parent", outer_vbox,
154                          "GtkWidget::visible", TRUE,
155                          NULL);
156
157   button = g_object_connect (gtk_widget_new (GTK_TYPE_CHECK_BUTTON,
158                                              "GtkButton::label", "Enable AccessX",
159                                              "GtkWidget::parent", hbox,
160                                              "GtkWidget::visible", TRUE,
161                                              NULL),
162                              "signal::clicked",
163                              toggle_accessx, NULL,
164                              NULL);
165   
166 /* FeatureFBMask seems not to work :-(
167    
168   control = control_struct_new (XkbAX_FeatureFBMask, &xkb->ctrls->ax_options, NULL, NULL);
169
170   button = g_object_connect (gtk_widget_new (GTK_TYPE_CHECK_BUTTON,
171                                              "GtkButton::label", "Notify Changes",
172                                              "GtkWidget::parent", hbox,
173                                              "GtkWidget::visible", TRUE,
174                                              NULL),
175                              "signal::clicked",
176                              toggle_xkb_notify_control, control,
177                              NULL);
178 */                           
179
180   gtk_widget_new (GTK_TYPE_HSEPARATOR,
181                   "GtkWidget::parent", outer_vbox,
182                   "GtkWidget::visible", TRUE,
183                   NULL);
184
185   hbox = gtk_widget_new (GTK_TYPE_HBOX,
186                          "GtkWidget::parent", outer_vbox,
187                          "GtkWidget::visible", TRUE,
188                          NULL);
189
190   control = control_struct_new (XkbStickyKeysMask, &xkb->ctrls->enabled_ctrls, NULL, NULL);
191
192   button = g_object_connect (gtk_widget_new (GTK_TYPE_CHECK_BUTTON,
193                                              "GtkButton::label", "Sticky Keys",
194                                              "GtkWidget::parent", hbox,
195                                              "GtkWidget::visible", TRUE,
196                                              NULL),
197                              "signal::clicked",
198                              toggle_xkb_control, control,
199                              NULL);
200   
201   control = control_struct_new (XkbAX_StickyKeysFBMask, &xkb->ctrls->ax_options, NULL, NULL);
202
203   button = g_object_connect (gtk_widget_new (GTK_TYPE_CHECK_BUTTON,
204                                              "GtkButton::label", "Beep when Latched",
205                                              "GtkWidget::parent", hbox,
206                                              "GtkWidget::visible", TRUE,
207                                              NULL),
208                              "signal::clicked",
209                              toggle_xkb_notify_control, control,
210                              NULL);
211   
212   frame = gtk_widget_new (gtk_frame_get_type(),
213                           "GtkFrame::label", "Slow Keys",
214                           "GtkWidget::parent", outer_vbox,
215                           "GtkWidget::visible", TRUE,
216                           NULL);
217     
218   vbox = gtk_widget_new (GTK_TYPE_VBOX,
219                          "GtkWidget::parent", frame,
220                          "GtkWidget::visible", TRUE,
221                          NULL);
222   
223   hbox = gtk_widget_new (GTK_TYPE_HBOX,
224                          "GtkWidget::parent", vbox,
225                          "GtkWidget::visible", TRUE,
226                          NULL);
227   
228   control = control_struct_new (XkbSlowKeysMask, &xkb->ctrls->slow_keys_delay, NULL, NULL);
229
230   button = g_object_connect (gtk_widget_new (GTK_TYPE_CHECK_BUTTON,
231                                              "GtkButton::label", "Enable Slow Keys",
232                                              "GtkWidget::parent", hbox,
233                                              "GtkWidget::visible", TRUE,
234                                              NULL),
235                              "signal::clicked",
236                              toggle_xkb_control, control,
237                              NULL);
238   
239   adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 1.0, 2000.0, 1.0, 10.0, 1.0 ));
240   
241   range = g_object_connect (gtk_widget_new (GTK_TYPE_HSCALE,
242                                             "GtkWidget::parent", hbox,
243                                             "GtkWidget::visible", TRUE,
244                                             "GtkRange::update_policy", GTK_UPDATE_DELAYED,
245                                             "GtkScale::digits", 0,
246                                             "GtkScale::adjustment", adjustment,
247                                             NULL),
248                             "signal::value_changed",
249                             set_accessx_control_value, control,
250                             NULL);
251   
252   gtk_widget_set_usize (GTK_WIDGET (range), 150, -1);
253   
254   label = gtk_widget_new (GTK_TYPE_LABEL,
255                           "GtkLabel::label", "Delay (mS)",
256                           "GtkWidget::parent", hbox,
257                           "GtkWidget::visible", TRUE,
258                           NULL);
259   
260   hbox = gtk_widget_new (GTK_TYPE_HBOX,
261                          "GtkWidget::parent", vbox,
262                          "GtkWidget::visible", TRUE,
263                          NULL);
264
265   control = control_struct_new (XkbAX_SKAcceptFBMask, &xkb->ctrls->ax_options, NULL, NULL);
266
267   button = g_object_connect (gtk_widget_new (GTK_TYPE_CHECK_BUTTON,
268                                              "GtkButton::label", "Beep on Accept",
269                                              "GtkWidget::parent", hbox,
270                                              "GtkWidget::visible", TRUE,
271                                              NULL),
272                              "signal::clicked",
273                              toggle_xkb_notify_control, control,
274                              NULL);
275   
276   control = control_struct_new (XkbAX_SKRejectFBMask, &xkb->ctrls->ax_options, NULL, NULL);
277
278   button = g_object_connect (gtk_widget_new (GTK_TYPE_CHECK_BUTTON,
279                                              "GtkButton::label", "Beep on Reject",
280                                              "GtkWidget::parent", hbox,
281                                              "GtkWidget::visible", TRUE,
282                                              NULL),
283                              "signal::clicked",
284                              toggle_xkb_notify_control, control,
285                              NULL);
286   
287   frame = gtk_widget_new (gtk_frame_get_type(),
288                           "GtkFrame::label", "Bounce Keys",
289                           "GtkWidget::parent", outer_vbox,
290                           "GtkWidget::visible", TRUE,
291                           NULL);
292     
293   vbox = gtk_widget_new (GTK_TYPE_VBOX,
294                          "GtkWidget::parent", frame,
295                          "GtkWidget::visible", TRUE,
296                          NULL);
297   
298   hbox = gtk_widget_new (GTK_TYPE_HBOX,
299                          "GtkWidget::parent", vbox,
300                          "GtkWidget::visible", TRUE,
301                          NULL);
302   
303   control = control_struct_new (XkbBounceKeysMask, &xkb->ctrls->debounce_delay, NULL, NULL);
304
305   button = g_object_connect (gtk_widget_new (GTK_TYPE_CHECK_BUTTON,
306                                              "GtkButton::label", "Enable Key Debounce",
307                                              "GtkWidget::parent", hbox,
308                                              "GtkWidget::visible", TRUE,
309                                              NULL),
310                              "signal::clicked",
311                              toggle_xkb_control, control,
312                              NULL);
313   
314   adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 1.0, 2000.0, 1.0, 10.0, 1.0 ));
315   
316   range = g_object_connect (gtk_widget_new (GTK_TYPE_HSCALE,
317                                             "GtkWidget::parent", hbox,
318                                             "GtkWidget::visible", TRUE,
319                                             "GtkRange::update_policy", GTK_UPDATE_DELAYED,
320                                             "GtkScale::digits", 0,
321                                             "GtkScale::adjustment", adjustment,
322                                             NULL),
323                             "signal::value_changed",
324                             set_accessx_control_value, control,
325                             NULL);
326   
327   gtk_widget_set_usize (GTK_WIDGET (range), 150, -1);
328   
329   label = gtk_widget_new (GTK_TYPE_LABEL,
330                           "GtkLabel::label", "Delay (mS)",
331                           "GtkWidget::parent", hbox,
332                           "GtkWidget::visible", TRUE,
333                           NULL);
334   
335   hbox = gtk_widget_new (GTK_TYPE_HBOX,
336                          "GtkWidget::parent", vbox,
337                          "GtkWidget::visible", TRUE,
338                          NULL);
339
340   control = control_struct_new (XkbAX_BKRejectFBMask, &xkb->ctrls->ax_options, NULL, NULL);
341
342   button = g_object_connect (gtk_widget_new (GTK_TYPE_CHECK_BUTTON,
343                                              "GtkButton::label", "Beep on Reject",
344                                              "GtkWidget::parent", hbox,
345                                              "GtkWidget::visible", TRUE,
346                                              NULL),
347                              "signal::clicked",
348                              toggle_xkb_notify_control, control,
349                              NULL);
350   
351   return outer_vbox;
352 }
353
354 static GtkWidget*
355 repeat_keys_box ()
356 {
357   GtkWidget *outer_hbox, *vbox, *label, *button, *range, *frame;
358   GtkAdjustment *adjustment;
359   AccessXControlStruct *control =
360           control_struct_new (XkbRepeatKeysMask, &xkb->ctrls->repeat_delay, NULL, NULL);
361   
362   frame = gtk_widget_new (gtk_frame_get_type(),
363                           "GtkFrame::label","Repeat Keys",
364                           "GtkWidget::visible", TRUE,
365                           NULL);
366   
367   outer_hbox = gtk_widget_new (GTK_TYPE_HBOX,
368                          "GtkWidget::visible", TRUE,
369                           "GtkWidget::parent", frame,
370                          NULL);
371
372   button = g_object_connect (gtk_widget_new (GTK_TYPE_CHECK_BUTTON,
373                                              "GtkButton::label", "Enable RepeatKeys",
374                                              "GtkWidget::parent", outer_hbox,
375                                              "GtkWidget::visible", TRUE,
376                                              NULL),
377                              "signal::clicked",
378                              toggle_xkb_control, control,
379                              NULL);
380   
381   gtk_box_set_child_packing (GTK_BOX (outer_hbox), button, FALSE, FALSE, 0, GTK_PACK_START);
382
383  
384   vbox = gtk_widget_new (GTK_TYPE_VBOX,
385                          "GtkWidget::visible", TRUE,
386                          "GtkWidget::parent", outer_hbox,
387                          NULL);
388
389   adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (200.0, 200.0, 4000.0, 10.0, 100.0, 10.0 ));
390   
391   range = g_object_connect (gtk_widget_new (GTK_TYPE_HSCALE,
392                                             "GtkWidget::parent", vbox,
393                                             "GtkWidget::visible", TRUE,
394                                             "GtkRange::update_policy", GTK_UPDATE_DELAYED,
395                                             "GtkScale::digits", 0,
396                                             "GtkScale::adjustment", adjustment,
397                                             NULL),
398                             "signal::value_changed",
399                             set_accessx_control_value, control,
400                             NULL);
401   
402   gtk_widget_set_usize (GTK_WIDGET (range), 150, -1);
403   
404   adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (200.0, 40.0, 4000.0, 1.0, 10.0, 1.0 ));
405   
406   control = control_struct_new (XkbRepeatKeysMask, &xkb->ctrls->repeat_interval, NULL, NULL);
407   
408   range = g_object_connect (gtk_widget_new (GTK_TYPE_HSCALE,
409                                             "GtkWidget::parent", vbox,
410                                             "GtkWidget::visible", TRUE,
411                                             "GtkRange::update_policy", GTK_UPDATE_DELAYED,
412                                             "GtkScale::digits", 0,
413                                             "GtkScale::adjustment", adjustment,
414                                             NULL),
415                             "signal::value_changed",
416                             set_accessx_control_value, control,
417                             NULL);
418   
419   gtk_widget_set_usize (GTK_WIDGET (range), 150, -1);
420
421   vbox = gtk_widget_new (GTK_TYPE_VBOX,
422                          "GtkWidget::visible", TRUE,
423                          "GtkWidget::parent", outer_hbox,
424                          NULL);
425   
426   label = gtk_widget_new (GTK_TYPE_LABEL,
427                           "GtkLabel::label", "Delay (mS)",
428                           "GtkWidget::parent", vbox,
429                           "GtkWidget::visible", TRUE,
430                           NULL);
431   
432   label = gtk_widget_new (GTK_TYPE_LABEL,
433                           "GtkLabel::label", "Interval (mS)",
434                           "GtkWidget::parent", vbox,
435                           "GtkWidget::visible", TRUE,
436                           NULL);
437    
438   return frame;
439 }
440
441 static GtkWidget*
442 mouse_keys_box ()
443 {
444   GtkWidget *outer_hbox, *vbox, *label, *button, *range, *frame;
445   GtkAdjustment *adjustment;
446   AccessXControlStruct *control =
447           control_struct_new (XkbMouseKeysMask, &xkb->ctrls->mk_delay, NULL, NULL);
448   
449   frame = gtk_widget_new (gtk_frame_get_type(),
450                           "GtkFrame::label","Mouse Keys",
451                           "GtkWidget::visible", TRUE,
452                           NULL);
453   
454   outer_hbox = gtk_widget_new (GTK_TYPE_HBOX,
455                          "GtkWidget::visible", TRUE,
456                           "GtkWidget::parent", frame,
457                          NULL);
458
459   button = g_object_connect (gtk_widget_new (GTK_TYPE_CHECK_BUTTON,
460                                              "GtkButton::label", "Enable MouseKeys",
461                                              "GtkWidget::parent", outer_hbox,
462                                              "GtkWidget::visible", TRUE,
463                                              NULL),
464                              "signal::clicked",
465                              toggle_xkb_control, control,
466                              NULL);
467   
468   gtk_box_set_child_packing (GTK_BOX (outer_hbox), button, FALSE, FALSE, 0, GTK_PACK_START);
469  
470   vbox = gtk_widget_new (GTK_TYPE_VBOX,
471                          "GtkWidget::visible", TRUE,
472                          "GtkWidget::parent", outer_hbox,
473                          NULL);
474
475   adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (200.0, 20.0, 4000.0, 10.0, 100.0, 10.0 ));
476   
477   control = control_struct_new (XkbRepeatKeysMask, &xkb->ctrls->mk_interval, NULL, NULL);
478   
479   range = g_object_connect (gtk_widget_new (GTK_TYPE_HSCALE,
480                                             "GtkWidget::parent", vbox,
481                                             "GtkWidget::visible", TRUE,
482                                             "GtkRange::update_policy", GTK_UPDATE_DELAYED,
483                                             "GtkScale::digits", 0,
484                                             "GtkScale::adjustment", adjustment,
485                                             NULL),
486                             "signal::value_changed",
487                             set_accessx_control_value, control,
488                             NULL);
489   
490   gtk_widget_set_usize (GTK_WIDGET (range), 150, -1);
491   
492   adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (800.0, 200.0, 4000.0, 1.0, 10.0, 1.0 ));
493   
494   control = control_struct_new (XkbRepeatKeysMask, &xkb->ctrls->mk_time_to_max, NULL, NULL);
495   
496   range = g_object_connect (gtk_widget_new (GTK_TYPE_HSCALE,
497                                             "GtkWidget::parent", vbox,
498                                             "GtkWidget::visible", TRUE,
499                                             "GtkRange::update_policy", GTK_UPDATE_DELAYED,
500                                             "GtkScale::digits", 0,
501                                             "GtkScale::adjustment", adjustment,
502                                             NULL),
503                             "signal::value_changed",
504                             set_accessx_control_value, control,
505                             NULL);
506   
507   gtk_widget_set_usize (GTK_WIDGET (range), 150, -1);
508   
509   adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (800.0, 200.0, 4000.0, 1.0, 10.0, 1.0 ));
510   
511   control = control_struct_new (XkbMouseKeysMask, &xkb->ctrls->mk_max_speed, NULL, NULL);
512   
513   range = g_object_connect (gtk_widget_new (GTK_TYPE_HSCALE,
514                                             "GtkWidget::parent", vbox,
515                                             "GtkWidget::visible", TRUE,
516                                             "GtkRange::update_policy", GTK_UPDATE_DELAYED,
517                                             "GtkScale::digits", 0,
518                                             "GtkScale::adjustment", adjustment,
519                                             NULL),
520                             "signal::value_changed",
521                             set_accessx_control_value, control,
522                             NULL);
523   
524   gtk_widget_set_usize (GTK_WIDGET (range), 150, -1);
525   
526   adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (800.0, 200.0, 4000.0, 1.0, 10.0, 1.0 ));
527   
528   control = control_struct_new (XkbMouseKeysMask, &xkb->ctrls->mk_curve, NULL, NULL);
529   
530   range = g_object_connect (gtk_widget_new (GTK_TYPE_HSCALE,
531                                             "GtkWidget::parent", vbox,
532                                             "GtkWidget::visible", TRUE,
533                                             "GtkRange::update_policy", GTK_UPDATE_DELAYED,
534                                             "GtkScale::digits", 0,
535                                             "GtkScale::adjustment", adjustment,
536                                             NULL),
537                             "signal::value_changed",
538                             set_accessx_control_value, control,
539                             NULL);
540   
541   vbox = gtk_widget_new (gtk_vbox_get_type(),
542                          "GtkWidget::name", "MouseKeys",
543                          "GtkWidget::parent", outer_hbox,
544                          "GtkWidget::visible", TRUE,
545                          "GtkContainer::border_width", 5,
546                          NULL);
547   label = gtk_widget_new (GTK_TYPE_LABEL,
548                           "GtkLabel::label", "Delay (mS)",
549                           "GtkWidget::parent", vbox,
550                           "GtkWidget::visible", TRUE,
551                           NULL);
552   
553   label = gtk_widget_new (GTK_TYPE_LABEL,
554                           "GtkLabel::label", "Accel. time (mS)",
555                           "GtkWidget::parent", vbox,
556                           "GtkWidget::visible", TRUE,
557                           NULL);
558   
559   label = gtk_widget_new (GTK_TYPE_LABEL,
560                           "GtkLabel::label", "Interval (mS)",
561                           "GtkWidget::parent", vbox,
562                           "GtkWidget::visible", TRUE,
563                           NULL);
564   
565   label = gtk_widget_new (GTK_TYPE_LABEL,
566                           "GtkLabel::label", "Max. Speed",
567                           "GtkWidget::parent", vbox,
568                           "GtkWidget::visible", TRUE,
569                           NULL);
570   
571   label = gtk_widget_new (GTK_TYPE_LABEL,
572                           "GtkLabel::label", "Curve",
573                           "GtkWidget::parent", vbox,
574                           "GtkWidget::visible", TRUE,
575                           NULL);
576   return frame;
577 }
578
579 static GtkWidget*
580 timeout_box ()
581 {
582   GtkWidget *hbox, *label, *button, *range;
583   GtkAdjustment *adjustment;
584   AccessXControlStruct *control =
585           control_struct_new (XkbAccessXTimeoutMask, &xkb->ctrls->ax_timeout, NULL, NULL);
586   
587   hbox = gtk_widget_new (gtk_hbox_get_type(),
588                           "GtkWidget::visible", TRUE,
589                           NULL);
590   
591   button = g_object_connect (gtk_widget_new (GTK_TYPE_CHECK_BUTTON,
592                                              "GtkButton::label", "AccessX Timeout",
593                                              "GtkWidget::parent", hbox,
594                                              "GtkWidget::visible", TRUE,
595                                              NULL),
596                              "signal::clicked",
597                              toggle_xkb_control, control,
598                              NULL);
599   
600   adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 1.0, 200.0, 1.0, 10.0, 1.0 ));
601   
602   range = g_object_connect (gtk_widget_new (GTK_TYPE_HSCALE,
603                                             "GtkWidget::parent", hbox,
604                                             "GtkWidget::visible", TRUE,
605                                             "GtkRange::update_policy", GTK_UPDATE_DELAYED,
606                                             "GtkScale::digits", 0,
607                                             "GtkScale::adjustment", adjustment,
608                                             NULL),
609                             "signal::value_changed",
610                             set_accessx_control_value, control,
611                             NULL);
612   
613   gtk_widget_set_usize (GTK_WIDGET (range), 150, -1);
614   
615   label = gtk_widget_new (GTK_TYPE_LABEL,
616                           "GtkLabel::label", "AccessX Timeout (Min.)",
617                           "GtkWidget::parent", hbox,
618                           "GtkWidget::visible", TRUE,
619                           NULL);
620   
621   return hbox;
622 }
623
624 static void
625 create_gui ()
626 {
627   GtkWidget *window, *button, *container, *hbox;
628   
629   window = g_object_connect (gtk_widget_new (gtk_window_get_type (),
630                                              "user_data", NULL,
631                                              "can_focus", FALSE,
632                                              "type", GTK_WINDOW_TOPLEVEL,
633                                              "window-position", GTK_WIN_POS_CENTER,
634                                              "title", "AccessX",
635                                              "allow_grow", TRUE,
636                                              "allow_shrink", TRUE,
637                                              "border_width", 10,
638                                              NULL),
639                              "signal::destroy", gui_exit, NULL,
640                              NULL);
641   
642   container = gtk_widget_new (GTK_TYPE_VBOX,
643                               "GtkWidget::parent", window,
644                               "GtkWidget::visible", TRUE,
645                               NULL);
646
647   /* create and add containers for: AccessX on/off,
648      basic toggles,
649      MouseKeys support, and timeout */
650
651   gtk_container_add (GTK_CONTAINER (container), basic_toggles_box ());
652   gtk_container_add (GTK_CONTAINER (container), repeat_keys_box ());
653 /*  gtk_container_add (GTK_CONTAINER (container), mouse_keys_box ());
654   gtk_container_add (GTK_CONTAINER (container), timeout_box ());*/
655
656   hbox = gtk_widget_new (gtk_hbox_get_type(),
657                          "GtkWidget::parent", container,
658                          "GtkWidget::visible", TRUE,
659                          "GtkContainer::border_width", 5,
660                          NULL);
661
662   button = g_object_connect (gtk_widget_new (gtk_button_get_type (),
663                                              "GtkButton::label", "Quit",
664                                              "GtkWidget::parent", hbox,
665                                              "GtkWidget::visible", TRUE,
666                                              NULL),
667                              "signal::clicked",
668                              gui_exit, NULL,
669                              NULL);
670
671   gtk_widget_show (window);     
672 }
673
674 static void
675 create_gui_x ()
676 {
677   GtkWidget *window, *button, *container, *hbox, *range;
678   GtkAdjustment *adjustment;
679   int i;
680   static AccessXControlStruct* controls[N_CONTROLS];
681   controls[0] = control_struct_new (XkbSlowKeysMask,   &xkb->ctrls->slow_keys_delay, "Slow Keys", "Delay, mS");
682   controls[1] = control_struct_new (XkbStickyKeysMask, &xkb->ctrls->ax_options, "Sticky Keys", NULL);
683   controls[2] = control_struct_new (XkbBounceKeysMask, &xkb->ctrls->debounce_delay, "Key Debounce", "Delay, mS");
684   controls[3] = control_struct_new (XkbRepeatKeysMask, &xkb->ctrls->repeat_delay, "Repeat Keys", "Delay, mS");
685   controls[4] = control_struct_new (XkbRepeatKeysMask, &xkb->ctrls->repeat_interval, NULL, "Interval, mS");
686   controls[5] = control_struct_new (XkbMouseKeysMask,  &xkb->ctrls->mk_delay, "MouseKeys", "Delay, mS");
687   controls[6] = control_struct_new (XkbMouseKeysAccelMask, &xkb->ctrls->mk_time_to_max, NULL, "Accel");
688   controls[7] = control_struct_new (XkbAccessXTimeoutMask, &xkb->ctrls->ax_timeout, "AccessX timeout", "Sec");
689   
690   
691   
692   hbox = gtk_widget_new (gtk_hbox_get_type(),
693                          "GtkWidget::parent", container,
694                          "GtkWidget::visible", TRUE,
695                          NULL);
696
697   i = 0; /* FIXME: this looks bogus */
698   button = g_object_connect (gtk_widget_new (gtk_check_button_get_type (),
699                                              "GtkButton::label", "Access X Timeout",
700                                              "GtkWidget::parent", hbox,
701                                              "GtkWidget::visible", TRUE,
702                                              NULL),
703                              "signal::clicked",
704                              toggle_xkb_control, controls[i],
705                              NULL);
706
707   adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 1.0, 200.0, 1.0, 10.0, 1.0 ));
708           
709   range = g_object_connect (gtk_widget_new (gtk_hscale_get_type (),
710                                             "GtkWidget::parent", hbox,
711                                             "GtkWidget::visible", TRUE,
712                                             "GtkScale::adjustment", adjustment,
713                                             NULL),
714                             "signal::value_changed",
715                             set_accessx_control_value, controls[i],
716                             NULL);
717           
718   gtk_widget_set_usize (GTK_WIDGET (range), 150, -1);
719   gtk_widget_new (gtk_label_get_type(),
720                   "GtkWidget::parent", hbox,
721                   "GtkLabel::label", controls[i]->val_label,
722                   "GtkWidget::visible", TRUE,
723                   NULL);
724
725   hbox = gtk_widget_new (gtk_hbox_get_type(),
726                          "GtkWidget::parent", container,
727                          "GtkWidget::visible", TRUE,
728                          "GtkContainer::border_width", 5,
729                          NULL);
730
731   button = g_object_connect (gtk_widget_new (gtk_button_get_type (),
732                                              "GtkButton::label", "Quit",
733                                              "GtkWidget::parent", hbox,
734                                              "GtkWidget::visible", TRUE,
735                                              NULL),
736                              "signal::clicked",
737                              gui_exit, NULL,
738                              NULL);
739
740   gtk_widget_show (window);
741 }
742
743 int
744 main(int argc, char **argv)
745 {
746   
747   if ((argc > 1) && (!strncmp(argv[1],"-h",2)))
748   {
749     printf ("Usage: keysynth-demo\n");
750     exit(0);
751   }
752
753   gtk_init (&argc, &argv); /* must call, because this program uses GTK+ */
754
755   if (!init_xkb ())
756   {
757      g_error ("Xkb extension not present, can't initialize accessX\n");
758   }
759   
760   create_gui ();
761   
762   gtk_main ();  
763
764   return 0;
765 }