cc19fae3183a376c0a1337c319b890c3576eccf9
[oweals/cde.git] / cde / programs / dtstyle / Keyboard.c
1 /************************************<+>*************************************
2  ****************************************************************************
3  **
4  **   File:        Keyboard.c
5  **
6  **   Project:     DT 3.0
7  **
8  **   Description: Controls the DtStyle keyboard dialog
9  **
10  **
11  **  (c) Copyright Hewlett-Packard Company, 1990.  
12  **
13  **
14  **
15  ****************************************************************************
16  ************************************<+>*************************************/
17 /* $XConsortium: Keyboard.c /main/4 1995/10/30 13:10:18 rswiston $ */
18
19 /*+++++++++++++++++++++++++++++++++++++++*/
20 /* include files                         */
21 /*+++++++++++++++++++++++++++++++++++++++*/
22
23 #include <X11/Xlib.h>
24 #include <Xm/MwmUtil.h>
25
26 #include <Xm/Xm.h>
27 #include <Xm/XmP.h>
28 #include <Xm/Form.h>
29 #include <Xm/LabelG.h>
30 #include <Xm/PushBG.h>
31 #include <Xm/Scale.h>
32 #include <Xm/ToggleBG.h>
33 #include <Xm/VendorSEP.h>
34
35 #include <Dt/DialogBox.h>
36 #include <Dt/Icon.h>
37
38 #include <Dt/Message.h>
39 #include <Dt/HourGlass.h>
40
41 #include "Help.h"
42 #include "Main.h"
43 #include "SaveRestore.h"
44 #include "Protocol.h"
45
46 /*+++++++++++++++++++++++++++++++++++++++*/
47 /* include extern functions              */
48 /*+++++++++++++++++++++++++++++++++++++++*/
49 #include "Keyboard.h"
50
51 /*+++++++++++++++++++++++++++++++++++++++*/
52 /* Local #defines                        */
53 /*+++++++++++++++++++++++++++++++++++++++*/
54 #define VOLUME_MAX       100
55 #define SCALE_WIDTH      200
56
57 /*+++++++++++++++++++++++++++++++++++++++*/
58 /* Internal Functions                    */
59 /*+++++++++++++++++++++++++++++++++++++++*/
60
61
62 static Widget build_keyboardDlg( Widget shell) ;
63 static void layoutCB( 
64                         Widget w,
65                         XtPointer client_data,
66                         XtPointer call_data) ;
67 static void _DtmapCB_keyboardDlg( 
68                         Widget w,
69                         XtPointer client_data,
70                         XtPointer call_data) ;
71 static int getValue( Widget w) ;
72 static void valueChangedCB( 
73                         Widget w,
74                         XtPointer client_data,
75                         XtPointer call_data) ;
76 static void autoRepeatToggleCB( 
77                         Widget w,
78                         XtPointer client_data,
79                         XtPointer call_data) ;
80 static void systemDefaultCB( 
81                         Widget w,
82                         XtPointer client_data,
83                         XtPointer call_data) ;
84 static void ButtonCB( 
85                         Widget w,
86                         XtPointer client_data,
87                         XtPointer call_data) ;
88
89
90 /*+++++++++++++++++++++++++++++++++++++++*/
91 /* Internal Variables                    */
92 /*+++++++++++++++++++++++++++++++++++++++*/
93
94 typedef struct {
95     Widget          pictLabel;
96     Widget          systemDefault;
97     Widget          volumeLabGad;
98     Widget          volumeScale;
99     Widget          autoRepeatToggle;
100     XKeyboardState  values;
101     int             new_key_click_percent;
102     int             new_autoRepeat;
103     Boolean         systemDefaultFlag;
104 } Kbd, *KdbPtr;
105
106 static Kbd kbd;
107 static saveRestore save = {FALSE, 0, };
108
109 /*+++++++++++++++++++++++++++++++++++++++*/
110 /* popup_kbdDialog                       */
111 /*+++++++++++++++++++++++++++++++++++++++*/
112 void 
113 popup_keyboardBB(
114         Widget shell )
115 {
116     if (style.kbdDialog == NULL) 
117     {
118       _DtTurnOnHourGlass(shell);  
119       build_keyboardDlg(shell);
120       XtManageChild(style.kbdDialog);
121       _DtTurnOffHourGlass(shell);  
122     }
123     else 
124     {
125       XtManageChild(style.kbdDialog);
126       raiseWindow(XtWindow(XtParent(style.kbdDialog)));
127     }
128 }
129
130 /*+++++++++++++++++++++++++++++++++++++++*/
131 /* build__keyboardDlg                    */
132 /*+++++++++++++++++++++++++++++++++++++++*/
133 static Widget 
134 build_keyboardDlg(
135         Widget shell )
136 {
137     register int     i, n;
138     Arg              args[MAX_ARGS];
139     Widget           widget_list[12]; 
140     int              count = 0;
141     Widget           form;
142     Pixel            foreground, background;
143     Boolean          set;
144     XmString         button_string[NUM_LABELS]; 
145     XmString         string;
146
147     /* Set up DialogBoxDialog button labels */
148     button_string[0] = CMPSTR(_DtOkString);
149     button_string[1] = CMPSTR(_DtCancelString);
150     button_string[2] = CMPSTR(_DtHelpString);
151
152     /* Create toplevel DialogBox */
153
154     /* saveRestore
155      * Note that save.poscnt has been initialized elsewhere.  
156      * save.posArgs may contain information from restoreBeep().*/
157
158     XtSetArg(save.posArgs[save.poscnt], XmNbuttonCount, NUM_LABELS);  
159     save.poscnt++;
160     XtSetArg(save.posArgs[save.poscnt], XmNbuttonLabelStrings, button_string);  
161     save.poscnt++;
162     XtSetArg (save.posArgs[save.poscnt], XmNdefaultPosition, False); 
163     save.poscnt++;
164     style.kbdDialog = __DtCreateDialogBoxDialog(shell, "KeyboardDialog", save.posArgs, save.poscnt);
165     XtAddCallback(style.kbdDialog, XmNcallback, ButtonCB, NULL);
166     XtAddCallback(style.kbdDialog, XmNhelpCallback,
167             (XtCallbackProc)HelpRequestCB, (XtPointer)HELP_KEYBOARD_DIALOG);
168
169     XmStringFree(button_string[0]);
170     XmStringFree(button_string[1]);
171     XmStringFree(button_string[2]);
172
173     widget_list[0] = _DtDialogBoxGetButton(style.kbdDialog,2);
174     n=0;
175     XtSetArg(args[n], XmNautoUnmanage, False); n++;
176     XtSetArg(args[n], XmNcancelButton, widget_list[0]); n++;
177     XtSetValues (style.kbdDialog, args, n);
178
179     n=0;
180     XtSetArg(args[n], XmNtitle, ((char *)GETMESSAGE(13, 6, "Style Manager - Keyboard"))); n++;
181     XtSetArg (args[n], XmNuseAsyncGeometry, True); n++;
182     XtSetArg(args[n], XmNmwmFunctions,  DIALOG_MWM_FUNC ); n++;
183     XtSetValues (XtParent(style.kbdDialog), args, n);
184
185     n = 0;
186     XtSetArg(args[n], XmNhorizontalSpacing, style.horizontalSpacing); n++;
187     XtSetArg(args[n], XmNverticalSpacing, style.verticalSpacing); n++;
188     XtSetArg(args[n], XmNallowOverlap, False); n++;
189     XtSetArg(args[n], XmNchildType, XmWORK_AREA);  n++;
190     form = XmCreateForm(style.kbdDialog, "keyboardForm", args, n);
191
192     /* create keyboard pixmap */
193
194     n = 0;
195     XtSetArg(args[n], XmNfillMode, XmFILL_SELF); n++;
196     XtSetArg(args[n], XmNbehavior, XmICON_LABEL); n++;
197     XtSetArg(args[n], XmNpixmapForeground, style.secBSCol); n++;
198     XtSetArg(args[n], XmNpixmapBackground, style.secTSCol); n++;
199     XtSetArg(args[n], XmNstring, NULL); n++;  
200     XtSetArg(args[n], XmNshadowThickness, 0); n++;  
201     XtSetArg(args[n], XmNimageName, KEYBOARD_ICON); n++;  
202     XtSetArg(args[n], XmNtraversalOn, False); n++;  
203     widget_list[count++] = 
204     kbd.pictLabel= _DtCreateIcon(form, "keyboardpictLabel", args, n);
205
206     n = 0;
207     XtSetArg(args[n], XmNmarginHeight, LB_MARGIN_HEIGHT);  n++;
208     XtSetArg(args[n], XmNmarginWidth, LB_MARGIN_WIDTH);  n++;
209     string = CMPSTR(((char *)GETMESSAGE(13, 2, "Default")));
210     XtSetArg(args[n], XmNlabelString, string); n++;
211     XtSetArg(args[n], XmNnavigationType, XmTAB_GROUP); n++;  
212     widget_list[count++] = 
213     kbd.systemDefault= XmCreatePushButtonGadget(form, "systemDefault", args, n);
214     XmStringFree(string);
215     
216     n = 0;
217     set = (kbd.values.global_auto_repeat == AutoRepeatModeOn) ? True : False;
218     XtSetArg(args[n], XmNset, set);  n++;
219     string = CMPSTR(((char *)GETMESSAGE(13, 3, "Auto Repeat")));
220     XtSetArg(args[n], XmNlabelString, string); n++;
221     XtSetArg(args[n], XmNnavigationType, XmTAB_GROUP); n++;  
222     widget_list[count++] = 
223     kbd.autoRepeatToggle= XmCreateToggleButtonGadget(form, "autoRepeatToggle", args, n);
224     XmStringFree(string);
225
226     n = 0;
227     XtSetArg(args[n], XmNalignment, XmALIGNMENT_END); n++;
228     string = CMPSTR(((char *)GETMESSAGE(13, 4, "Click Volume")));
229     XtSetArg(args[n], XmNmarginHeight, 0); n++;
230     XtSetArg(args[n], XmNlabelString, string); n++;
231     widget_list[count++] = 
232     kbd.volumeLabGad= XmCreateLabelGadget(form,"volumeLabGad", args, n);
233     XmStringFree(string);
234
235     n = 0;
236     XtSetArg(args[n], XmNmaximum, VOLUME_MAX); n++; 
237     XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
238     XtSetArg(args[n], XmNprocessingDirection, XmMAX_ON_RIGHT); n++;
239     XtSetArg(args[n], XmNshowValue, True); n++;
240     XtSetArg(args[n], XmNhighlightThickness, SCALE_HIGHLIGHT_THICKNESS); n++; 
241     XtSetArg(args[n], XmNscaleWidth, SCALE_WIDTH); n++; 
242     widget_list[count++] = 
243     kbd.volumeScale= XmCreateScale(form,"volumeScale", args, n);
244
245     XtAddCallback(style.kbdDialog, XmNmapCallback, layoutCB, NULL);
246     XtAddCallback(style.kbdDialog, XmNmapCallback, _DtmapCB_keyboardDlg, shell);
247     XtAddCallback(kbd.systemDefault, XmNactivateCallback, systemDefaultCB, NULL);
248     XtAddCallback(kbd.volumeScale, XmNvalueChangedCallback, valueChangedCB, NULL);
249     XtAddCallback(kbd.autoRepeatToggle, XmNvalueChangedCallback, autoRepeatToggleCB, NULL);
250
251     XtManageChild(form);
252     XtManageChildren(widget_list,count); 
253
254     return(style.kbdDialog);
255 }
256
257 /*+++++++++++++++++++++++++++++++++++++++*/
258 /* layoutCB                              */
259 /*+++++++++++++++++++++++++++++++++++++++*/
260 static void 
261 layoutCB(
262         Widget w,
263         XtPointer client_data,
264         XtPointer call_data )
265 {
266     int              n;
267     Arg              args[MAX_ARGS];
268
269     /* Picture Label */
270     n=0;
271     XtSetArg(args[n], XmNtopAttachment,      XmATTACH_FORM);       n++;
272     XtSetArg(args[n], XmNtopOffset,          style.verticalSpacing);    n++;
273     XtSetArg(args[n], XmNbottomAttachment,   XmATTACH_NONE);       n++;
274     XtSetArg(args[n], XmNleftAttachment,     XmATTACH_FORM);       n++;
275     XtSetArg(args[n], XmNleftOffset,         style.horizontalSpacing);  n++;
276     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_NONE);       n++;
277     XtSetValues (kbd.pictLabel, args, n);
278
279     /* system Default */
280     n=0;
281     XtSetArg(args[n], XmNtopAttachment,      XmATTACH_FORM);       n++;
282     XtSetArg(args[n], XmNtopOffset,          style.verticalSpacing);    n++;
283     XtSetArg(args[n], XmNbottomAttachment,   XmATTACH_NONE);       n++;
284     XtSetArg(args[n], XmNleftAttachment,     XmATTACH_NONE);       n++;
285     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_FORM);       n++;
286     XtSetArg(args[n], XmNrightOffset,        style.horizontalSpacing);  n++;
287     XtSetValues (kbd.systemDefault, args, n);
288
289     /* auto repeat toggle */
290     n=0;
291     XtSetArg(args[n], XmNtopAttachment,      XmATTACH_WIDGET);     n++;
292     XtSetArg(args[n], XmNtopWidget,          kbd.pictLabel);       n++;
293     XtSetArg(args[n], XmNtopOffset,          style.verticalSpacing); n++;
294     XtSetArg(args[n], XmNbottomAttachment,   XmATTACH_NONE);       n++;
295     XtSetArg(args[n], XmNleftAttachment,     XmATTACH_FORM);       n++;
296     XtSetArg(args[n], XmNleftOffset,         style.horizontalSpacing);  n++;
297     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_NONE);       n++;
298     XtSetValues (kbd.autoRepeatToggle, args, n);
299
300     /* Volume Label */
301     n=0;
302
303     XtSetArg(args[n], XmNtopAttachment,      XmATTACH_NONE);     n++;
304     XtSetArg(args[n], XmNbottomAttachment,   XmATTACH_FORM);       n++;
305     XtSetArg(args[n], XmNbottomOffset,       style.verticalSpacing);    n++;
306     XtSetArg(args[n], XmNleftAttachment,     XmATTACH_FORM);       n++;
307     XtSetArg(args[n], XmNleftOffset,         style.horizontalSpacing);  n++;
308     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_NONE);       n++;
309     XtSetValues (kbd.volumeLabGad, args, n);
310
311
312     /* Volume Scale */
313     n=0;
314     XtSetArg(args[n], XmNtopAttachment,      XmATTACH_WIDGET);     n++;
315     XtSetArg(args[n], XmNtopWidget,          kbd.autoRepeatToggle);n++;
316     XtSetArg(args[n], XmNtopOffset,          style.verticalSpacing);n++;
317     XtSetArg(args[n], XmNbottomAttachment,   XmATTACH_FORM); n++;
318     XtSetArg(args[n], XmNbottomOffset,       style.verticalSpacing);  n++;
319     XtSetArg(args[n], XmNleftAttachment,     XmATTACH_WIDGET);     n++;
320     XtSetArg(args[n], XmNleftWidget,         kbd.volumeLabGad);    n++;
321     XtSetArg(args[n], XmNleftOffset,         style.horizontalSpacing);  n++;
322     XtSetArg(args[n], XmNrightAttachment,    XmATTACH_FORM);       n++;
323     XtSetValues (kbd.volumeScale, args, n);
324
325     XtRemoveCallback(style.kbdDialog, XmNmapCallback, layoutCB, NULL);
326 }
327
328
329 /*+++++++++++++++++++++++++++++++++++++++*/
330 /* _DtmapCB_keyboardDlg                     */
331 /*+++++++++++++++++++++++++++++++++++++++*/
332 static void 
333 _DtmapCB_keyboardDlg(
334         Widget w,
335         XtPointer client_data,
336         XtPointer call_data )
337 {
338     static int  first_time = 1;
339     int         n;
340     Arg         args[MAX_ARGS];
341     Boolean     set;
342
343     if (first_time)
344     {
345         DtWsmRemoveWorkspaceFunctions(style.display, XtWindow(XtParent(w)));
346
347         if (!save.restoreFlag)
348             putDialog ((Widget)client_data, w);
349
350         first_time = 0;
351     }
352
353     /* get keyboard values for click volume */
354     XGetKeyboardControl(style.display, &kbd.values);
355     kbd.new_key_click_percent = kbd.values.key_click_percent;
356     kbd.new_autoRepeat = kbd.values.global_auto_repeat;
357
358     n=0;
359     XtSetArg(args[n], XmNvalue, kbd.values.key_click_percent); n++;
360     XtSetValues(kbd.volumeScale, args, n);
361
362     n=0;
363     set = (kbd.values.global_auto_repeat == AutoRepeatModeOn) ? True : False;
364     XtSetArg(args[n], XmNset, set);  n++;
365     XtSetValues(kbd.autoRepeatToggle, args, n);
366 }
367
368 static int 
369 getValue(
370         Widget w )
371 {
372     int n, value;
373     Arg args[1];
374
375     n=0;
376     XtSetArg(args[n], XmNvalue, &value); n++;
377     XtGetValues(w, args, n);
378     return(value);
379 }
380
381
382 /*+++++++++++++++++++++++++++++++++++++++*/
383 /* valueChangedCB                        */
384 /*+++++++++++++++++++++++++++++++++++++++*/
385 static void 
386 valueChangedCB(
387         Widget w,
388         XtPointer client_data,
389         XtPointer call_data )
390 {
391
392     XKeyboardControl    kbdControl;
393     int                 kbdControlMask;
394
395     /* set keyboard click volume to scale value */
396
397     kbdControlMask = KBKeyClickPercent;
398     kbdControl.key_click_percent = kbd.new_key_click_percent =
399                   getValue(kbd.volumeScale);
400     XChangeKeyboardControl(style.display, kbdControlMask, &kbdControl);
401     kbd.systemDefaultFlag = False;
402 }
403
404 /*+++++++++++++++++++++++++++++++++++++++*/
405 /* autoRepeatToggleCB                    */
406 /*+++++++++++++++++++++++++++++++++++++++*/
407 static void 
408 autoRepeatToggleCB(
409         Widget w,
410         XtPointer client_data,
411         XtPointer call_data )
412 {
413
414     /* set auto repeat to new value */
415
416     if (((XmToggleButtonCallbackStruct *)call_data)->set)
417     {
418         XAutoRepeatOn(style.display);
419         kbd.new_autoRepeat = AutoRepeatModeOn;
420     }
421     else
422     {
423         XAutoRepeatOff(style.display);
424         kbd.new_autoRepeat = AutoRepeatModeOff;
425     }
426     kbd.systemDefaultFlag = False;
427 }
428
429 /*+++++++++++++++++++++++++++++++++++++++*/
430 /* systemDefaultCB                       */
431 /*+++++++++++++++++++++++++++++++++++++++*/
432 static void 
433 systemDefaultCB(
434         Widget w,
435         XtPointer client_data,
436         XtPointer call_data )
437 {
438     int                 n;
439     Arg                 args[MAX_ARGS];
440     XKeyboardControl    kbdControl;
441     int                 kbdControlMask;
442     XKeyboardState      kbdState;
443     Boolean             set;
444
445     /* set keyboard click volume to system default value */
446
447     kbdControlMask = KBKeyClickPercent | KBAutoRepeatMode;
448     kbdControl.key_click_percent = -1;
449     kbdControl.auto_repeat_mode = AutoRepeatModeDefault;
450     XChangeKeyboardControl(style.display, kbdControlMask, &kbdControl);
451
452     XGetKeyboardControl(style.display, &kbdState);
453
454     n=0;
455     XtSetArg(args[n], XmNvalue, kbdState.key_click_percent); n++;
456     XtSetValues(kbd.volumeScale, args, n);
457
458     n=0;
459     set = (kbdState.global_auto_repeat == AutoRepeatModeOn) ? True : False;
460     XtSetArg(args[n], XmNset, set);  n++;
461     XtSetValues(kbd.autoRepeatToggle, args, n);
462
463     kbd.systemDefaultFlag = True;
464 }
465
466 /*+++++++++++++++++++++++++++++++++++++++*/
467 /* ButtonCB                              */
468 /* callback for PushButtons in DialogBox */
469 /*+++++++++++++++++++++++++++++++++++++++*/
470 static void 
471 ButtonCB(
472         Widget w,
473         XtPointer client_data,
474         XtPointer call_data )
475 {
476     int                 n;
477     Arg                 args[MAX_ARGS];
478     XKeyboardControl    kbdControl;
479     int                 kbdControlMask;
480     DtDialogBoxCallbackStruct *cb = (DtDialogBoxCallbackStruct *) call_data;
481
482
483     switch (cb->button_position)
484     {
485       case OK_BUTTON:
486           XtUnmanageChild (w);
487
488           /* if sendSettings is true send message to Session Manager */
489
490           if(style.smState.smSendSettings)
491           {
492              if(kbd.systemDefaultFlag)
493              {
494                 SmDefaultKeyboardSettings();
495              }
496              else
497              {
498                 SmNewKeyboardSettings( kbd.new_key_click_percent, /* 0-100 */
499                                        kbd.new_autoRepeat);       /* 0,1   */
500              }
501           }
502           break;
503
504       case CANCEL_BUTTON:
505           /* reset to incoming keyboard values */ 
506
507           n=0;
508           XtSetArg(args[n], XmNvalue, kbd.values.key_click_percent); n++;
509           XtSetValues(kbd.volumeScale, args, n);
510
511           n=0;
512           XtSetArg(args[n], XmNset, kbd.values.global_auto_repeat); n++;
513           XtSetValues(kbd.autoRepeatToggle, args, n);
514
515           kbdControlMask = KBKeyClickPercent | KBAutoRepeatMode;
516           kbdControl.key_click_percent = kbd.values.key_click_percent;
517           kbdControl.auto_repeat_mode = kbd.values.global_auto_repeat;
518           XChangeKeyboardControl(style.display, kbdControlMask, &kbdControl);
519
520           XtUnmanageChild(w);
521           break;
522
523       case HELP_BUTTON:
524           XtCallCallbacks(style.kbdDialog, XmNhelpCallback, (XtPointer)NULL);
525           break;
526
527       default:
528           break;
529     }
530 }
531
532
533 /************************************************************************
534  * restoreKeybd()
535  *
536  * restore any state information saved with saveKeybd.
537  * This is called from restoreSession with the application
538  * shell and the special xrm database retrieved for restore.
539  ************************************************************************/
540 void 
541 restoreKeybd(
542         Widget shell,
543         XrmDatabase db )
544 {
545     XrmName xrm_name[5];
546     XrmRepresentation rep_type;
547     XrmValue value;
548
549     xrm_name [0] = XrmStringToQuark ("keyboardDlg");
550     xrm_name [2] = NULL;
551
552     /* get x position */
553     xrm_name [1] = XrmStringToQuark ("x");
554     if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value)){
555       XtSetArg (save.posArgs[save.poscnt], XmNx, atoi((char *)value.addr)); save.poscnt++;
556       save.restoreFlag = True;
557     }
558
559     /* get y position */
560     xrm_name [1] = XrmStringToQuark ("y");
561     if (XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value)){
562       XtSetArg (save.posArgs[save.poscnt], XmNy, atoi((char *)value.addr)); save.poscnt++;
563     }
564
565     xrm_name [1] = XrmStringToQuark ("ismapped");
566     XrmQGetResource (db, xrm_name, xrm_name, &rep_type, &value);
567     /* Are we supposed to be mapped? */
568     if (strcmp(value.addr, "True") == 0)
569       popup_keyboardBB(shell);
570 }
571
572 /************************************************************************
573  * saveKeybd()
574  *
575  * This routine will write out to the passed file descriptor any state
576  * information this dialog needs.  It is called from saveSessionCB with the
577  * file already opened.
578  * All information is saved in xrm format.  There is no restriction
579  * on what can be saved.  It doesn't have to be defined or be part of any
580  * widget or Xt definition.  Just name and save it here and recover it in
581  * restoreBackdrop.  The suggested minimum is whether you are mapped, and your
582  * location.
583  ************************************************************************/
584 void 
585 saveKeybd(
586         int fd )
587 {
588     Position x,y;
589     char *bufr = style.tmpBigStr;     /* size=[1024], make bigger if needed */
590     XmVendorShellExtObject  vendorExt;
591     XmWidgetExtData         extData;
592
593     if (style.kbdDialog != NULL) 
594     {
595         if (XtIsManaged(style.kbdDialog))
596             sprintf(bufr, "*keyboardDlg.ismapped: True\n");
597         else
598             sprintf(bufr, "*keyboardDlg.ismapped: False\n");
599
600         /* Get and write out the geometry info for our Window */
601         x = XtX(XtParent(style.kbdDialog));
602         y = XtY(XtParent(style.kbdDialog));
603
604         /* Modify x & y to take into account window mgr frames
605          * This is pretty bogus, but I don't know a better way to do it.
606          */
607         extData = _XmGetWidgetExtData(style.shell, XmSHELL_EXTENSION);
608         vendorExt = (XmVendorShellExtObject)extData->widget;
609         x -= vendorExt->vendor.xOffset;
610         y -= vendorExt->vendor.yOffset;
611
612         sprintf(bufr, "%s*keyboardDlg.x: %d\n", bufr, x);
613         sprintf(bufr, "%s*keyboardDlg.y: %d\n", bufr, y);
614
615         write (fd, bufr, strlen(bufr));
616     }
617 }
618