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