Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtwm / WmFeedback.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* 
24  * (c) Copyright 1989, 1990, 1991, 1992, 1993 OPEN SOFTWARE FOUNDATION, INC. 
25  * ALL RIGHTS RESERVED 
26 */ 
27 /* 
28  * Motif Release 1.2.3
29 */ 
30 #ifdef REV_INFO
31 #ifndef lint
32 static char rcsid[] = "$XConsortium: WmFeedback.c /main/6 1996/10/23 17:20:55 rswiston $"
33 #endif
34 #endif
35 /*
36  * (c) Copyright 1987, 1988, 1989, 1990 HEWLETT-PACKARD COMPANY */
37
38 /*
39  * Included Files:
40  */
41 #include "WmGlobal.h"
42 #include "WmResNames.h"
43
44 #define MWM_NEED_TIME16
45 #include "WmBitmap.h"
46
47 #include <Xm/Xm.h>
48 #include <X11/Shell.h>
49 #include <Xm/Label.h>
50 #include <Xm/DialogS.h>
51 #include <Xm/BulletinB.h>
52 #include <Xm/MessageB.h>
53
54 #define MOVE_OUTLINE_WIDTH      2
55 #define FEEDBACK_BEVEL          2
56
57 #define DEFAULT_POSITION_STRING "(0000x0000)"
58
59 #define  CB_HIGHLIGHT_THICKNESS  3
60
61 /*
62  * include extern functions
63  */
64 #include "WmFeedback.h"
65 #include "WmFunction.h"
66 #include "WmGraphics.h"
67 #ifdef PANELIST
68 #include "WmPanelP.h"  /* for typedef in WmManage.h */
69 #endif /* PANELIST */
70 #include "WmManage.h"
71 #include "WmColormap.h"
72 #include "stdio.h"
73
74
75 /*
76  * Global Variables:
77  */
78 static Cursor  waitCursor = (Cursor)0L;
79
80 /* see WmGlobal.h for index defines: */
81
82 #ifndef NO_MESSAGE_CATALOG
83 static char *confirm_mesg[4] = {"Switch to Default Behavior?",
84                                 "Switch to Custom Behavior?",
85                                 "Restart Mwm?",
86                                 "QUIT Mwm?"};
87
88
89 void
90 initMesg()
91 {
92
93     char * tmpString;
94
95     /*
96      * catgets returns a pointer to an area that is over written
97      * on each call to catgets.  
98      */
99
100     tmpString = ((char *)GETMESSAGE(22, 12, "Switch to Default Behavior?"));
101     if ((confirm_mesg[0] =
102          (char *)XtMalloc ((unsigned int) (strlen(tmpString) + 1))) == NULL)
103     {
104         Warning (((char *)GETMESSAGE(22, 2, "Insufficient memory for local message string")));
105         confirm_mesg[0] = "Switch to Default Behavior?";
106     }
107     else
108     {
109         strcpy(confirm_mesg[0], tmpString);
110     }
111
112     tmpString = ((char *)GETMESSAGE(22, 13, "Switch to Custom Behavior?"));
113     if ((confirm_mesg[1] =
114          (char *)XtMalloc ((unsigned int) (strlen(tmpString) + 1))) == NULL)
115     {
116         Warning (((char *)GETMESSAGE(22, 2, "Insufficient memory for local message string")));
117         confirm_mesg[1] = "Switch to Custom Behavior?";
118     }
119     else
120     {
121         strcpy(confirm_mesg[1], tmpString);
122     }
123
124     if (MwmBehavior)
125     {
126         tmpString = ((char *)GETMESSAGE(22, 3, "Restart Mwm?"));
127     }
128     else
129     {
130         tmpString = ((char *)GETMESSAGE(22, 10, "Restart Workspace Manager?"));
131     }
132     if ((confirm_mesg[2] =
133          (char *)XtMalloc ((unsigned int) (strlen(tmpString) + 1))) == NULL)
134     {
135         Warning (((char *)GETMESSAGE(22, 5, "Insufficient memory for local message string")));
136         if (MwmBehavior)
137         {
138             confirm_mesg[2] = "Restart Mwm?";
139         }
140         else
141         {
142             confirm_mesg[2] = "Restart Workspace Manager?";
143         }
144     }
145     else
146     {
147         strcpy(confirm_mesg[2], tmpString);
148     }
149
150
151
152     if (MwmBehavior)
153     {
154         tmpString = ((char *)GETMESSAGE(22, 6, "QUIT Mwm?"));
155     }
156     else
157     {
158 #ifdef MINIMAL_DT
159         if (wmGD.dtLite)
160         {
161             tmpString = ((char *)GETMESSAGE(22, 9, "Log out?"));
162         }
163         else
164         {
165             tmpString = ((char *)GETMESSAGE(22, 11, "QUIT Workspace Manager?"));
166         }
167 #else /* MINIMAL_DT */
168         tmpString = ((char *)GETMESSAGE(22, 11, "QUIT Workspace Manager?"));
169 #endif /* MINIMAL_DT */
170     }
171     
172     if ((confirm_mesg[3] =
173          (char *)XtMalloc ((unsigned int) (strlen(tmpString) + 1))) == NULL)
174     {
175         Warning (((char *)GETMESSAGE(22, 8, "Insufficient memory for local message string")));
176         if (MwmBehavior)
177         {
178             confirm_mesg[3] = "QUIT Mwm?";
179         }
180         else
181 #ifdef MINIMAL_DT
182         if (wmGD.dtLite)
183         {
184             confirm_mesg[3] = "Log out?";
185         }
186         else
187         {
188             confirm_mesg[3] = "QUIT Workspace Manager?";
189         }
190 #else /* MINIMAL_DT */
191         tmpString = ((char *)GETMESSAGE(22, 11, "QUIT Workspace Manager?"));
192 #endif /* MINIMAL_DT */
193     }
194     else
195     {
196         strcpy(confirm_mesg[3], tmpString);
197     }
198
199
200 }
201 #else
202 static char *confirm_mesg[4] = {"Toggle to Default Behavior?",
203                                 "Toggle to Custom Behavior?",
204                                 "Restart Mwm?",
205                                 "QUIT Mwm?"};
206
207 #endif
208 static char *confirm_widget[4] = {"confirmDefaultBehavior",
209                                   "confirmCustomBehavior",
210                                   "confirmRestart",
211                                   "confirmQuit"};
212
213
214 typedef void (*ConfirmFunc)(Boolean);
215 static ConfirmFunc confirm_func[4] = {Do_Set_Behavior,
216                                       Do_Set_Behavior,
217                                       Do_Restart,
218                                       Do_Quit_Mwm};
219
220 \f
221 /*************************************<->*************************************
222  *
223  *  ShowFeedbackWindow(pSD, x, y, width, height, style)
224  *
225  *
226  *  Description:
227  *  -----------
228  *  Pop up the window for moving and sizing feedback
229  *
230  *
231  *  Inputs:
232  *  ------
233  *  pSD         - pointer to screen data
234  *  x           - initial x-value
235  *  y           - initial y-value
236  *  width       - initial width value
237  *  height      - initial height value
238  *  style       - show size, position, or both
239  *  
240  * 
241  *  Outputs:
242  *  -------
243  *
244  *
245  *  Comments:
246  *  --------
247  *************************************<->***********************************/
248 void ShowFeedbackWindow (WmScreenData *pSD, int x, int y, unsigned int width, unsigned int height, unsigned long style)
249 {
250     unsigned long        mask = 0;
251     XSetWindowAttributes win_attribs;
252     XWindowChanges       win_changes;
253     int                  direction, ascent, descent;
254     XCharStruct          xcsLocation;
255     int                  winX, winY;
256     int                  tmpX, tmpY;
257
258     if ( (pSD->fbStyle = style) == FB_OFF)
259         return;
260
261     pSD->fbLastX = x;
262     pSD->fbLastY = y;
263     pSD->fbLastWidth = width;
264     pSD->fbLastHeight = height;
265
266     /*
267      * Derive the size and position of the window from the text extents
268      * Set starting position of each string 
269      */
270     XTextExtents(pSD->feedbackAppearance.font, DEFAULT_POSITION_STRING, 
271                  strlen(DEFAULT_POSITION_STRING), &direction, &ascent, 
272                  &descent, &xcsLocation);
273     
274     pSD->fbWinWidth = xcsLocation.width + 4*FEEDBACK_BEVEL;
275
276     switch (pSD->fbStyle) 
277     {
278         case FB_SIZE:
279             pSD->fbSizeY = 2*FEEDBACK_BEVEL + ascent;
280             pSD->fbWinHeight = (ascent + descent) + 4*FEEDBACK_BEVEL;
281             break;
282
283         case FB_POSITION:
284             pSD->fbLocY = 2*FEEDBACK_BEVEL + ascent;
285             pSD->fbWinHeight = (ascent + descent) + 4*FEEDBACK_BEVEL;
286             break;
287
288         default:
289         case (FB_SIZE | FB_POSITION):
290             pSD->fbLocY = 2*FEEDBACK_BEVEL + ascent;
291             pSD->fbSizeY = pSD->fbLocY + ascent + descent;
292             pSD->fbWinHeight = 2*(ascent + descent) + 4*FEEDBACK_BEVEL;
293             break;
294     }
295
296     if (pSD->feedbackGeometry) /* set by user */
297     {
298         unsigned int junkWidth, junkHeight;
299
300         mask = XParseGeometry(pSD->feedbackGeometry, &tmpX, &tmpY,
301                               &junkWidth, &junkHeight);
302     }
303
304     if (mask & (XValue|YValue))
305     {
306         winX = (mask & XNegative) ? 
307             DisplayWidth(DISPLAY, pSD->screen)  + tmpX - pSD->fbWinWidth : tmpX;
308         winY = (mask & YNegative) ? 
309             DisplayHeight(DISPLAY, pSD->screen) + tmpY -pSD->fbWinHeight : tmpY;
310     }
311     else
312     {
313         winX = (DisplayWidth(DISPLAY, pSD->screen) - pSD->fbWinWidth)/2;
314         winY = (DisplayHeight(DISPLAY, pSD->screen) -pSD->fbWinHeight)/2;
315     }
316
317     /* 
318      * Put new text into the feedback strings
319      */
320     UpdateFeedbackText (pSD, x, y, width, height);
321
322     /*
323      * bevel the window border for a 3-D look
324      */
325     if ( (pSD->fbTop && pSD->fbBottom) ||
326          ((pSD->fbTop = AllocateRList((unsigned)2*FEEDBACK_BEVEL)) &&
327           (pSD->fbBottom = AllocateRList((unsigned)2*FEEDBACK_BEVEL))) )
328     {
329         pSD->fbTop->used = 0;
330         pSD->fbBottom->used = 0;
331         BevelRectangle (pSD->fbTop,
332                         pSD->fbBottom,
333                         0, 0, 
334                         pSD->fbWinWidth, pSD->fbWinHeight,
335                         FEEDBACK_BEVEL, FEEDBACK_BEVEL,
336                         FEEDBACK_BEVEL, FEEDBACK_BEVEL);
337     }
338
339     /*
340      * Create window if not yet created, otherwise fix size and position
341      */
342
343     if (!pSD->feedbackWin)
344     {
345
346         /*
347          * Create the window
348          */
349
350         mask = CWEventMask | CWOverrideRedirect | CWSaveUnder;
351         win_attribs.event_mask = ExposureMask;
352         win_attribs.override_redirect = TRUE;
353         win_attribs.save_under = TRUE;
354
355         /* 
356          * Use background pixmap if one is specified, otherwise set the
357          * appropriate background color. 
358          */
359
360         if (pSD->feedbackAppearance.backgroundPixmap)
361         {
362             mask |= CWBackPixmap;
363             win_attribs.background_pixmap =
364                                 pSD->feedbackAppearance.backgroundPixmap;
365         }
366         else
367         {
368             mask |= CWBackPixel;
369             win_attribs.background_pixel =
370                                 pSD->feedbackAppearance.background;
371         }
372
373         pSD->feedbackWin = XCreateWindow (DISPLAY, pSD->rootWindow, 
374                                           winX, winY,
375                                           pSD->fbWinWidth, 
376                                           pSD->fbWinHeight,
377                                           0, CopyFromParent, 
378                                           InputOutput, CopyFromParent, 
379                                           mask, &win_attribs);
380     }
381     else
382     {
383         win_changes.x = winX;
384         win_changes.y = winY;
385         win_changes.width = pSD->fbWinWidth;
386         win_changes.height = pSD->fbWinHeight;
387         win_changes.stack_mode = Above;
388
389         mask = CWX | CWY | CWWidth | CWHeight | CWStackMode;
390
391         XConfigureWindow(DISPLAY, pSD->feedbackWin, (unsigned int) mask, 
392             &win_changes);
393     }
394
395
396     /*
397      * Make the feedback window visible (map it)
398      */
399
400     if (pSD->feedbackWin)
401     {
402         /* Make sure the feedback window doesn't get buried */
403         XRaiseWindow(DISPLAY, pSD->feedbackWin);
404         XMapWindow (DISPLAY, pSD->feedbackWin);
405         PaintFeedbackWindow(pSD);
406     }
407
408 } /* END OF FUNCTION ShowFeedbackWindow */
409
410
411 \f
412 /*************************************<->*************************************
413  *
414  *  PaintFeedbackWindow(pSD)
415  *
416  *
417  *  Description:
418  *  -----------
419  *  Repaints the feedback window in response to exposure events
420  *
421  *
422  *  Inputs:
423  *  ------
424  *  pSD         - pointer to screen data
425  * 
426  *  Outputs:
427  *  -------
428  *
429  *
430  *  Comments:
431  *  --------
432  *************************************<->***********************************/
433 void PaintFeedbackWindow (WmScreenData *pSD)
434 {
435     if (pSD->feedbackWin)
436     {
437         /* 
438          * draw beveling 
439          */
440         if (pSD->fbTop->used > 0) 
441         {
442             XFillRectangles (DISPLAY, pSD->feedbackWin, 
443                              pSD->feedbackAppearance.inactiveTopShadowGC,
444                              pSD->fbTop->prect, pSD->fbTop->used);
445         }
446         if (pSD->fbBottom->used > 0) 
447         {
448             XFillRectangles (DISPLAY, pSD->feedbackWin, 
449                              pSD->feedbackAppearance.inactiveBottomShadowGC,
450                              pSD->fbBottom->prect, 
451                              pSD->fbBottom->used);
452         }
453
454         /*
455          * clear old text 
456          */
457         XClearArea (DISPLAY, pSD->feedbackWin, 
458                     FEEDBACK_BEVEL, FEEDBACK_BEVEL,
459                     pSD->fbWinWidth-2*FEEDBACK_BEVEL, 
460                     pSD->fbWinHeight-2*FEEDBACK_BEVEL,
461                     FALSE);
462
463         /*
464          * put up new text
465          */
466         if (pSD->fbStyle & FB_POSITION) 
467         {
468             WmDrawString (DISPLAY, pSD->feedbackWin, 
469                          pSD->feedbackAppearance.inactiveGC,
470                          pSD->fbLocX, pSD->fbLocY, 
471                          pSD->fbLocation, strlen(pSD->fbLocation));
472         }
473         if (pSD->fbStyle & FB_SIZE) 
474         {
475             WmDrawString (DISPLAY, pSD->feedbackWin, 
476                          pSD->feedbackAppearance.inactiveGC,
477                          pSD->fbSizeX, pSD->fbSizeY, 
478                          pSD->fbSize, strlen(pSD->fbSize));
479         }
480     }
481 }
482
483
484 \f
485 /*************************************<->*************************************
486  *
487  *  HideFeedbackWindow (pSD)
488  *
489  *
490  *  Description:
491  *  -----------
492  *  Hide the feedback window
493  *
494  *
495  *  Inputs:
496  *  ------
497  *  pDS         - pointer to screen data
498  * 
499  *  Outputs:
500  *  -------
501  *
502  *
503  *  Comments:
504  *  --------
505  * 
506  *************************************<->***********************************/
507 void HideFeedbackWindow (WmScreenData *pSD)
508 {
509     if (pSD->feedbackWin)
510     {
511         XUnmapWindow (DISPLAY, pSD->feedbackWin);
512 #ifndef OLD_COLORMAP
513         ForceColormapFocus (ACTIVE_PSD, ACTIVE_PSD->colormapFocus);
514 #endif
515     }
516     pSD->fbStyle = FB_OFF;
517 }
518
519
520
521 \f
522 /*************************************<->*************************************
523  *
524  *  UpdateFeedbackInfo (pSD, x, y, width, height)
525  *
526  *
527  *  Description:
528  *  -----------
529  *  Update the information in the feedback window
530  *
531  *
532  *  Inputs:
533  *  ------
534  *  pSD         - pointer to screen info
535  *  x           - x-value
536  *  y           - y-value
537  *  width       - width value
538  *  height      - height value
539  *
540  * 
541  *  Outputs:
542  *  -------
543  *
544  *
545  *  Comments:
546  *  --------
547  * 
548  *************************************<->***********************************/
549 void UpdateFeedbackInfo (WmScreenData *pSD, int x, int y, unsigned int width, unsigned int height)
550 {
551     /*
552      * Currently the feedback window must always be redrawn to (potentially)
553      * repair damage done by moving the configuration outline.  The feedback
554      * repainting generally only needs to be done when the information
555      * changes or the feedback window is actually overwritten by the
556      * configuration outline.
557      */
558
559 #ifdef NOTDONE
560     /* only update if something changed */
561     if (((pSD->fbStyle & FB_POSITION) &&
562          ((pSD->fbLastX != x) || (pSD->fbLastY != y))) || 
563         ((pSD->fbStyle & FB_SIZE) &&
564          ((pSD->fbLastWidth != width) || (pSD->fbLastHeight != height))))
565 #endif /* NOTDONE */
566     {
567         pSD->fbLastX = x;
568         pSD->fbLastY = y;
569         pSD->fbLastWidth = width;
570         pSD->fbLastHeight = height;
571
572         UpdateFeedbackText (pSD, x, y, width, height);
573
574         PaintFeedbackWindow(pSD);
575     }
576 }
577
578
579
580 \f
581 /*************************************<->*************************************
582  *
583  *  UpdateFeedbackText (pSD, x, y, width, height)
584  *
585  *
586  *  Description:
587  *  -----------
588  *  Update the information in the feedback strings
589  *
590  *
591  *  Inputs:
592  *  ------
593  *  pSD         - pointer to screen data
594  *  x           - x-value
595  *  y           - y-value
596  *  width       - width value
597  *  height      - height value
598  *
599  * 
600  *  Outputs:
601  *  -------
602  *
603  *
604  *  Comments:
605  *  --------
606  * 
607  *************************************<->***********************************/
608 void UpdateFeedbackText (WmScreenData *pSD, int x, int y, unsigned int width, unsigned int height)
609 {
610     int         direction, ascent, descent;
611     XCharStruct xcs;
612
613     if (pSD->fbStyle & FB_POSITION) 
614     {
615         sprintf (pSD->fbLocation, "(%4d,%-4d)", x, y);
616         XTextExtents(pSD->feedbackAppearance.font, pSD->fbLocation,
617                  strlen(pSD->fbLocation), &direction, &ascent, 
618                  &descent, &xcs);
619         pSD->fbLocX = (pSD->fbWinWidth - xcs.width)/2;
620     }
621
622     if (pSD->fbStyle & FB_SIZE) 
623     {
624         sprintf (pSD->fbSize,     "%4dx%-4d", width, height);
625         XTextExtents(pSD->feedbackAppearance.font, pSD->fbSize,
626                  strlen(pSD->fbSize), &direction, &ascent, 
627                  &descent, &xcs);
628         pSD->fbSizeX = (pSD->fbWinWidth - xcs.width)/2;
629     }
630 }
631
632
633 \f
634 /*************************************<->*************************************
635  *
636  *  static void
637  *  OkCB (w, client_data, call_data)
638  *
639  *
640  *  Description:
641  *  -----------
642  *  QuestionBox Ok callback.
643  *
644  *
645  *  Inputs:
646  *  ------
647  *  None.
648  *
649  * 
650  *  Outputs:
651  *  -------
652  *  None.
653  *
654  *
655  *  Comments:
656  *  --------
657  *  None.
658  * 
659  *************************************<->***********************************/
660
661 static void OkCB (w, client_data, call_data)
662
663    Widget w;
664    caddr_t client_data;
665    caddr_t call_data;
666 {
667     WithdrawDialog (w);
668
669     confirm_func[((WmScreenData *)client_data)->actionNbr] (False);
670
671     wmGD.confirmDialogMapped = False;
672
673 } /* END OF FUNCTION OkCB */
674
675 \f
676 /*************************************<->*************************************
677  *
678  *  static void
679  *  CancelCB (w, client_data, call_data)
680  *
681  *
682  *  Description:
683  *  -----------
684  *  QuestionBox Cancel callback.
685  *
686  *
687  *  Inputs:
688  *  ------
689  *  None.
690  *
691  * 
692  *  Outputs:
693  *  -------
694  *  None.
695  *
696  *
697  *  Comments:
698  *  --------
699  *  None.
700  * 
701  *************************************<->***********************************/
702
703 static void CancelCB (w, client_data, call_data)
704
705    Widget w;
706    caddr_t client_data;
707    caddr_t call_data;
708 {
709     WithdrawDialog (w);
710
711     wmGD.confirmDialogMapped = False;
712
713 } /* END OF FUNCTION CancelCB */
714
715
716 \f
717 /*************************************<->*************************************
718  *
719  *  void
720  *  ConfirmAction (pSD,nbr)
721  *
722  *
723  *  Description:
724  *  -----------
725  *  Post a QuestionBox and ask for confirmation.  If so, executes the
726  *  appropriate action.
727  *
728  *
729  *  Inputs:
730  *  ------
731  *  nbr = action number
732  *  pSD->screen
733  *  pSD->screenTopLevel
734  *
735  * 
736  *  Outputs:
737  *  -------
738  *  actionNbr = current QuestionBox widget index.
739  *  confirmW[actionNbr]  = QuestionBox widget.
740  *
741  *
742  *  Comments:
743  *  --------
744  * 
745  *************************************<->***********************************/
746
747 void ConfirmAction (WmScreenData *pSD, int nbr)
748 {
749     Arg           args[8];
750     register int  n;
751     int           x, y;
752     Dimension     width, height;
753     Widget        dialogShellW = NULL;
754     XmString      messageString;
755     static XmString       defaultMessageString = NULL;
756
757
758     /*
759      * If there is a system modal window, don't post another
760      * one.  We need to think about a way to let a new system
761      * modal window be posted, and when unposted, restore the
762      * modal state of the current system modal window.  
763      */
764
765     if(wmGD.systemModalActive)
766     {
767         return ;
768     }
769
770     if (pSD->confirmboxW[nbr] == NULL)
771     /* First time for this one */
772     {
773 #ifndef NO_MESSAGE_CATALOG
774         /*
775          * Initialize messages
776          */
777         initMesg();
778 #endif
779
780         /* 
781          * Create a dialog popup shell with explicit keyboard policy.
782          */
783
784         n = 0;
785         XtSetArg(args[n], XmNx, (XtArgVal)
786                  (DisplayWidth (DISPLAY, pSD->screen)/2)); n++;
787         XtSetArg(args[n], XmNy, (XtArgVal)
788                  (DisplayHeight (DISPLAY, pSD->screen)/2)); n++;
789         XtSetArg(args[n], XtNallowShellResize, (XtArgVal) TRUE);  n++;
790         XtSetArg(args[n], XtNkeyboardFocusPolicy, (XtArgVal) XmEXPLICIT);  n++;
791         XtSetArg(args[n], XtNdepth, 
792                 (XtArgVal) DefaultDepth(DISPLAY, pSD->screen));  n++;
793         XtSetArg(args[n], XtNscreen, 
794                 (XtArgVal) ScreenOfDisplay(DISPLAY, pSD->screen));  n++;
795
796         dialogShellW =
797                 XtCreatePopupShell ((String) WmNfeedback, 
798                                     transientShellWidgetClass,
799                                     pSD->screenTopLevelW, args, n);
800
801         /* 
802          * Create a QuestionBox as a child of the popup shell.
803          * Set traversalOn and add callbacks for the OK and CANCEL buttons.
804          * Unmanage the HELP button.
805          */
806
807         n = 0;
808         XtSetArg(args[n], XmNdialogType, (XtArgVal) XmDIALOG_QUESTION); n++;
809         XtSetArg(args[n], XmNmessageAlignment, (XtArgVal) XmALIGNMENT_CENTER);
810            n++;
811         XtSetArg(args[n], XmNtraversalOn, (XtArgVal) TRUE); n++;
812
813         /*
814          * In 1.2 confirmbox's widget name changed from the generic
815          * WmNconfirmbox (ie. 'confirmbox') to a more descriptive name
816          * so that each confirm dialog can be customized separately (e.g.
817          * "Mwm*confirmRestart*messageString: restart it?").
818          */
819
820         pSD->confirmboxW[nbr] = 
821             XtCreateManagedWidget (confirm_widget[nbr], xmMessageBoxWidgetClass,
822                                    dialogShellW, args, n);
823
824         n = 0;
825         XtSetArg(args[n], XmNmessageString, &messageString); n++;
826         XtGetValues(pSD->confirmboxW[nbr], (ArgList) args, n);
827
828         if (defaultMessageString == NULL)
829         {
830             defaultMessageString = XmStringCreateLocalized ("");
831         }
832
833         n = 0;
834
835         /*
836          * If the message string is the default, then put something
837          * 'reasonable' in instead.
838          */
839
840         if (XmStringCompare( messageString, defaultMessageString ))
841         {
842             messageString = XmStringCreateLocalized(confirm_mesg[nbr]);
843             XtSetArg(args[n], XmNmessageString, (XtArgVal) messageString); n++;
844             XtSetValues(pSD->confirmboxW[nbr], (ArgList) args, n);
845             XmStringFree(messageString);
846         }
847
848         n = 0;
849         XtSetArg (args[n], XmNtraversalOn, (XtArgVal) TRUE); n++;
850         XtSetArg (args[n], XmNhighlightThickness, 
851                   (XtArgVal) CB_HIGHLIGHT_THICKNESS); n++;
852 #ifndef NO_MESSAGE_CATALOG
853         XtSetArg(args[n], XmNlabelString, wmGD.okLabel); n++;
854 #endif
855         XtSetValues ( XmMessageBoxGetChild (pSD->confirmboxW[nbr], 
856                             XmDIALOG_OK_BUTTON), args, n);
857 #ifndef NO_MESSAGE_CATALOG
858         n--;
859         XtSetArg(args[n], XmNlabelString, wmGD.cancelLabel); n++;
860 #endif
861         XtSetValues ( XmMessageBoxGetChild (pSD->confirmboxW[nbr], 
862                             XmDIALOG_CANCEL_BUTTON), args, n);
863         XtAddCallback (pSD->confirmboxW[nbr], XmNokCallback, 
864             (XtCallbackProc)OkCB, (XtPointer)pSD); 
865         XtAddCallback (pSD->confirmboxW[nbr], XmNcancelCallback, 
866             (XtCallbackProc)CancelCB, (XtPointer)NULL); 
867
868         XtUnmanageChild
869             (XmMessageBoxGetChild (pSD->confirmboxW[nbr], 
870                 XmDIALOG_HELP_BUTTON));
871
872         XtRealizeWidget (dialogShellW);
873
874         /* 
875          * Center the DialogShell in the display.
876          */
877
878         n = 0;
879         XtSetArg(args[n], XmNheight, &height); n++;
880         XtSetArg(args[n], XmNwidth, &width); n++;
881         XtGetValues (dialogShellW, (ArgList) args, n);
882
883         x = (DisplayWidth (DISPLAY, pSD->screen) - ((int) width))/2;
884         y = (DisplayHeight (DISPLAY, pSD->screen) - ((int) height))/2;
885         n = 0;
886         XtSetArg(args[n], XmNx, (XtArgVal) x); n++;
887         XtSetArg(args[n], XmNy, (XtArgVal) y); n++;
888         XtSetValues (dialogShellW, (ArgList) args, n);
889
890         ManageWindow (pSD, XtWindow(dialogShellW), MANAGEW_CONFIRM_BOX);
891     }
892     else
893     {
894         ReManageDialog (pSD, pSD->confirmboxW[nbr]);
895     }
896
897     pSD->actionNbr = nbr;
898
899     XFlush(DISPLAY);
900
901     wmGD.confirmDialogMapped = True;
902
903 } /* END OF FUNCTION ConfirmAction */
904
905
906 \f
907 /*************************************<->*************************************
908  *
909  *  ShowWaitState (flag)
910  *
911  *
912  *  Description:
913  *  -----------
914  *  Enter/Leave the wait state.
915  *
916  *
917  *  Inputs:
918  *  ------
919  *  flag = TRUE for Enter, FALSE for Leave.
920  *
921  * 
922  *  Outputs:
923  *  -------
924  *  None.
925  *
926  *
927  *  Comments:
928  *  --------
929  *  None.
930  * 
931  *************************************<->***********************************/
932
933 void ShowWaitState (Boolean flag)
934 {
935     char        *bits;
936     char        *maskBits;
937     unsigned int width;
938     unsigned int height;
939     unsigned int xHotspot;
940     unsigned int yHotspot;
941     Pixmap       pixmap;
942     Pixmap       maskPixmap;
943     XColor       xcolors[2];
944
945     if (!waitCursor)
946     {
947 #ifdef LARGECURSORS
948         if (wmGD.useLargeCursors)
949         {
950             width = time32_width;
951             height = time32_height;
952             bits = (char *)time32_bits;
953             maskBits = (char *)time32m_bits;
954             xHotspot = time32_x_hot;
955             yHotspot = time32_y_hot;
956         }
957         else
958 #endif /* LARGECURSORS */
959
960         {
961             width = time16_width;
962             height = time16_height;
963             bits = (char *)time16_bits;
964             maskBits = (char *)time16m_bits;
965             xHotspot = time16_x_hot;
966             yHotspot = time16_y_hot;
967         }
968
969         pixmap = XCreateBitmapFromData (DISPLAY, 
970                          DefaultRootWindow(DISPLAY), bits, 
971                          width, height);
972
973         maskPixmap = XCreateBitmapFromData (DISPLAY, 
974                          DefaultRootWindow(DISPLAY), maskBits, 
975                          width, height);
976 #ifdef INTEGRATION_TESTING_
977         xcolors[1].pixel = BlackPixelOfScreen(DefaultScreenOfDisplay(DISPLAY));
978         xcolors[0].pixel = WhitePixelOfScreen(DefaultScreenOfDisplay(DISPLAY));
979 #else /* INTEGRATION_TESTING */
980
981         xcolors[0].pixel = BlackPixelOfScreen(DefaultScreenOfDisplay(DISPLAY));
982         xcolors[1].pixel = WhitePixelOfScreen(DefaultScreenOfDisplay(DISPLAY));
983
984 #endif /* INTEGRATION_TESTING */
985         XQueryColors (DISPLAY, 
986                       DefaultColormapOfScreen(DefaultScreenOfDisplay
987                                               (DISPLAY)), 
988                       xcolors, 2);
989         waitCursor = XCreatePixmapCursor (DISPLAY, pixmap, maskPixmap,
990                                           &(xcolors[0]), &(xcolors[1]),
991                                           xHotspot, yHotspot);
992         XFreePixmap (DISPLAY, pixmap);
993         XFreePixmap (DISPLAY, maskPixmap);
994     }
995
996     if (flag)
997     {
998         XGrabPointer (DISPLAY, DefaultRootWindow(DISPLAY), FALSE, 
999                         0, GrabModeAsync, GrabModeAsync, None, 
1000                         waitCursor, CurrentTime);
1001         XGrabKeyboard (DISPLAY, DefaultRootWindow(DISPLAY), FALSE, 
1002                         GrabModeAsync, GrabModeAsync, CurrentTime);
1003     }
1004     else
1005     {
1006         XUngrabPointer (DISPLAY, CurrentTime);
1007         XUngrabKeyboard (DISPLAY, CurrentTime);
1008     }
1009
1010 } /* END OF FUNCTION ShowWaitState */
1011
1012
1013 \f
1014 /*************************************<->*************************************
1015  *
1016  *  InitCursorInfo ()
1017  *
1018  *
1019  *  Description:
1020  *  -----------
1021  *  This function determines whether a server supports large cursors.  It it
1022  *  does large feedback cursors are used in some cases (wait state and
1023  *  system modal state); otherwise smaller (16x16) standard cursors are used.
1024  *
1025  *  Outputs:
1026  *  -------
1027  *  wmGD.useLargeCusors = set to True if larger cursors are supported.
1028  * 
1029  *************************************<->***********************************/
1030
1031 void InitCursorInfo (void)
1032 {
1033     unsigned int cWidth;
1034     unsigned int cHeight;
1035
1036     wmGD.useLargeCursors = False;
1037
1038     if (XQueryBestCursor (DISPLAY, DefaultRootWindow(DISPLAY), 
1039         32, 32, &cWidth, &cHeight))
1040     {
1041         if ((cWidth >= 32) && (cHeight >= 32))
1042         {
1043             wmGD.useLargeCursors = True;
1044         }
1045     }
1046
1047 } /* END OF FUNCTION InitCursorInfo */
1048
1049
1050
1051
1052
1053