Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtwm / WmPresence.c
1 #ifdef WSM
2 /* 
3  * (c) Copyright 1987, 1988, 1989, 1990, 1992 HEWLETT-PACKARD COMPANY 
4  * ALL RIGHTS RESERVED 
5 */ 
6 #ifdef REV_INFO
7 #ifndef lint
8 static char rcsid[] = "$XConsortium: WmPresence.c /main/7 1996/10/23 17:24:56 rswiston $"
9 #endif
10 #endif
11
12 /*
13  * Included Files:
14  */
15
16 #include "WmGlobal.h"
17 #include "WmResNames.h"
18 #include "WmHelp.h"
19
20 #include <X11/Core.h>
21 #include <X11/StringDefs.h>
22 #include <X11/Intrinsic.h>
23 #include <X11/Xatom.h>
24 #include <X11/Shell.h>
25 #include <Xm/Xm.h>
26 #include <Xm/Form.h>
27 #include <Xm/PushBG.h>
28 #include <Xm/LabelG.h>
29 #include <Xm/List.h>
30 #include <Xm/SeparatoG.h>
31 #include <Xm/ToggleB.h>
32 #ifndef  PANELIST
33 #include <Dt/Help.h>
34 #endif /* PANELIST */
35 #include <errno.h>
36 #include <signal.h>
37 #include <stdio.h>
38
39 /*
40  * Function Declarations:
41  */
42
43 #include "WmPresence.h"
44
45 /********    Static Function Declarations    ********/
46
47 static void wspSetWindowName( 
48                         PtrWsPresenceData pPres) ;
49 static Boolean wspCreateWidgets( 
50                         WmScreenData *pSD) ;
51 static Widget wspCreateShell( 
52                         WmScreenData *pSD) ;
53 static Widget wspCreateManager( 
54                         Widget shellW) ;
55 static Widget wspCreateLabel( 
56                         Widget mgrW,
57                         unsigned char *pchName,
58                         unsigned char *pchString) ;
59 static Widget wspCreateSeparator( 
60                         Widget mgrW) ;
61 static Widget wspCreateWorkspaceList( 
62                         Widget mgrW,
63                         PtrWsPresenceData pPres,
64                         WmScreenData *pSD) ;
65 static void wspUpdateWorkspaceList( 
66                         PtrWsPresenceData pPres) ;
67 static Widget wspCreateToggleButton( 
68                         Widget mgrW,
69                         unsigned char *pch) ;
70 static Widget wspCreatePushButton( 
71                         Widget mgrW,
72                         char *name,
73                         XmString label) ;
74 static void wspSetPosition( 
75                         PtrWsPresenceData pPres) ;
76 static void wspLayout( 
77                         PtrWsPresenceData pPres) ;
78 static void wspOkCB( 
79                         Widget buttonW,
80                         WmScreenData *pSD,
81                         XtPointer call_data) ;
82 static void wspHelpCB( 
83                         Widget buttonW,
84                         XtPointer client_data,
85                         XtPointer call_data) ;
86 static void wspAllWsCB( 
87                         Widget buttonW,
88                         WmScreenData *pSD,
89                         XmToggleButtonCallbackStruct *xmTbcs) ;
90 static void wspCancelCB( 
91                         Widget buttonW,
92                         XtPointer client_data,
93                         XtPointer call_data) ;
94 static void wspExtendedSelectCB(
95                         Widget w,
96                         XtPointer client_data,
97                         XmListCallbackStruct *cb );
98 static Dimension wspCharWidth (
99                         XmFontList xmfl);
100
101 /********    End Static Function Declarations    ********/
102
103 /*
104  * External references
105  */
106 #include "WmCDecor.h"
107 #include "WmCDInfo.h"
108 #include "WmIconBox.h"
109 #ifdef PANELIST
110 #include "WmPanelP.h"  /* for typedef in WmManage.h */
111 #endif /* PANELIST */
112 #include "WmManage.h"
113 #include "WmResParse.h"
114 #include "WmResource.h"
115 #include "WmWinInfo.h"
116 #include "WmWrkspace.h"
117
118
119 /*
120  * Global Variables:
121  */
122 /* 
123  * These two XmStrings are used in the workspace
124  * presence box to indicate the name of the current
125  * window for whice the presence box is active.  If the
126  * window is iconified, the title will be "Icon:  <iconName>",
127  * otherwise the title wil be "Window: <windowName>
128  */
129 XmString windowLabelString = (XmString)NULL;
130 XmString iconLabelString = (XmString)NULL;
131 \f
132 /*************************************<->*************************************
133  *
134  *  Boolean
135  *  MakePresenceBox (pSD)
136  *
137  *
138  *  Description:
139  *  -----------
140  *
141  *
142  *  Inputs:
143  *  ------
144  *  pSD = pointer to screen data
145  *
146  * 
147  *  Outputs:
148  *  -------
149  *  Return = (Boolean) True if successful
150  *
151  *
152  *  Comments:
153  *  --------
154  * 
155  ******************************<->***********************************/
156
157 Boolean 
158 MakePresenceBox(
159         WmScreenData *pSD )
160
161 {
162     PtrWsPresenceData pPres = &pSD->presence;
163     Boolean       rval;
164
165     /*
166      * Create the widgets for the workspace presence dialog
167      */   
168
169     pPres->onScreen = False;
170
171     if (wspCreateWidgets (pSD))
172     {
173         /*
174          * lay out the form
175          */
176         wspLayout (pPres);
177
178         /*
179          * Set the ClientData fields.
180          */   
181         XtRealizeWidget (pPres->shellW);
182 #ifdef PANELIST
183         DtWsmRemoveWorkspaceFunctions (DISPLAY1, XtWindow(pPres->shellW));
184 #endif /* PANELIST */
185
186         ProcessPresenceResources (pSD);
187
188         rval = True;
189     }
190     else
191     {
192         Warning(((char *)GETMESSAGE(52, 1, "Unable to create Occupy Workspace dialog.")));
193         rval = False;
194     }
195
196     return (rval);
197
198 } /* END OF FUNCTION MakePresenceBox */
199
200 \f
201 /*************************************<->*************************************
202  *
203  *  void
204  *  ShowPresenceBox (pClient, wsContext)
205  *
206  *
207  *  Description:
208  *  -----------
209  *  Pops up (shows) the workspace presence dialog
210  *
211  *  Inputs:
212  *  ------
213  *  pClient = pointer to client data which needs a presence dialog
214  *            up. (This is not the presence dialog's client data!!!)
215  *
216  *  wsContext = context to post dialog for 
217  *
218  * 
219  *  Outputs:
220  *  -------
221  *  Return = none
222  *
223  *
224  *  Comments:
225  *  --------
226  * 
227  ******************************<->***********************************/
228
229 void 
230 ShowPresenceBox(
231         ClientData *pClient,
232         Context wsContext )
233 {
234     PtrWsPresenceData pPres;
235     WmScreenData *pSD;
236
237     pPres = &pClient->pSD->presence;
238     pSD = pClient->pSD;
239     pPres->pCDforClient = pClient;
240     pPres->contextForClient = wsContext;
241
242     /*
243      * Create the presence dialog if not done yet.
244      */
245     if (!pSD->presence.shellW)
246     {
247         pPres->ItemSelected = NULL;
248         pPres->ItemStrings = NULL;
249         pPres->currentWsItem = 0;
250
251         MakePresenceBox (pSD);
252     }
253
254     if (pPres->onScreen)
255     {
256         HidePresenceBox (pSD, True);
257     }
258
259     /* update workspace list  */
260     wspUpdateWorkspaceList (pPres);
261
262     /*  set position of dialog relative to client window  */
263     wspSetPosition (pPres);
264
265     /* 
266      * pop it up 
267      */
268     XtPopup (pPres->shellW, XtGrabNone);
269     pPres->onScreen = True;
270 } /* END OF FUNCTION  ShowPresenceBox */
271
272 \f
273 /*************************************<->*************************************
274  *
275  *  static void
276  *  wspSetWindowName (pPres)
277  *
278  *
279  *  Description:
280  *  -----------
281  *  Sets the name of the current window in the presence dialog
282  *
283  *  Inputs:
284  *  ------
285  *  pPres = ptr to workspace presence dialog data
286  * 
287  *  Outputs:
288  *  -------
289  *  Return = none
290  *
291  *
292  *  Comments:
293  *  --------
294  * 
295  ******************************<->***********************************/
296
297 static void 
298 wspSetWindowName(
299         PtrWsPresenceData pPres )
300
301 {
302     int nameN, labelN;
303     Arg nameArgs[1];
304     Arg labelArgs[1];
305
306     /*
307      *  Set the name of the current window
308      */
309
310     nameN = 0;
311     labelN = 0;
312     if (pPres->contextForClient == F_CONTEXT_ICON)
313     {
314         XtSetArg (nameArgs[nameN], XmNlabelString, 
315                   pPres->pCDforClient->iconTitle);      nameN++;
316         XtSetArg (labelArgs[labelN], XmNlabelString, 
317                   iconLabelString);                     labelN++;
318     }
319     else
320     {
321         XtSetArg (nameArgs[nameN], XmNlabelString, 
322                   pPres->pCDforClient->clientTitle);    nameN++;
323         XtSetArg (labelArgs[labelN], XmNlabelString, 
324                   windowLabelString);                   labelN++;
325     }
326
327     XtSetValues (pPres->windowNameW, nameArgs, nameN);
328     XtSetValues (pPres->windowLabelW, labelArgs, labelN);
329
330 } /* END OF FUNCTION  wspSetWindowName */
331
332 \f
333 /*************************************<->*************************************
334  *
335  *  void
336  *  HidePresenceBox (pSD, userDismissed)
337  *
338  *
339  *  Description:
340  *  -----------
341  *  Pops down (hides) the workspace presence dialog
342  *
343  *  Inputs:
344  *  ------
345  *  pSD = pointer to screen data
346  *  userDismissed = did the user dismiss or did workspace switching 
347  *                  unpost the workspace presence box ?
348  * 
349  *  Outputs:
350  *  -------
351  *  Return = none
352  *
353  *
354  *  Comments:
355  *  --------
356  * 
357  ******************************<->***********************************/
358
359 void 
360 HidePresenceBox(
361         WmScreenData *pSD,
362         Boolean userDismissed )
363
364 {
365     if (pSD->presence.onScreen)
366     {
367         /* Pop down the shell */
368         XtPopdown (pSD->presence.shellW);
369
370         /* 
371          * Do a withdraw to make sure window gets unmanaged
372          * (popdown does nothing if its unmapped)
373          */
374         XWithdrawWindow (DISPLAY, XtWindow (pSD->presence.shellW),
375                          pSD->screen);
376         /* must sync to insure event order */
377         XSync (DISPLAY, False);
378
379
380         pSD->presence.onScreen = False;
381         pSD->presence.userDismissed = userDismissed;
382     }
383 } /* END OF FUNCTION   */
384
385 \f
386 /*************************************<->*************************************
387  *
388  *  wspCreateWidgets (pSD)
389  *
390  *
391  *  Description:
392  *  -----------
393  *  Creates all the widgets for the workspace presence dialog box
394  *
395  *  Inputs:
396  *  ------
397  *  pSD = pointer to screen data
398  * 
399  *  Outputs:
400  *  -------
401  *  Return = false on any failure
402  *
403  *  Comments:
404  *  ---------
405  *  Only creates widgets
406  ******************************<->***********************************/
407 static Boolean 
408 wspCreateWidgets(
409         WmScreenData *pSD )
410 {
411     PtrWsPresenceData pPres = &pSD->presence;
412     Arg args [5];
413     int n;
414     Boolean rval /* = True */;
415 #ifdef NO_MESSAGE_CATALOG
416     XmString tmpXmString;
417 #endif /* NO_MESSAGE_CATALOG */
418
419     rval = ((pPres->shellW = wspCreateShell (pSD)) != NULL);
420
421     if (rval)
422     {
423         rval = ((pPres->formW = wspCreateManager (pPres->shellW)) != NULL);
424     }
425
426     if (rval)
427     {
428         rval = ((pPres->windowLabelW = wspCreateLabel (pPres->formW,
429                         (unsigned char *)"window", 
430                          NULL))  != NULL);
431     }
432
433     if (rval)
434     {
435         rval = ((pPres->windowNameW = wspCreateLabel (pPres->formW, 
436                         (unsigned char *)"windowName", 
437                         (unsigned char *)" ")) != NULL);
438     }
439
440     if (rval)
441     {
442         rval = ((pPres->workspaceLabelW = 
443                 wspCreateLabel (pPres->formW, (unsigned char *)"workspaces", 
444                ((unsigned char *)GETMESSAGE(52, 3, "Workspaces: ")))) != NULL);
445     }
446
447     if (rval)
448     {
449         rval = ((pPres->workspaceListW =
450                 wspCreateWorkspaceList (pPres->formW, pPres, pSD)) != NULL);
451         pPres->workspaceScrolledListW = XtParent (pPres->workspaceListW);
452     }
453
454     if (rval)
455     {
456         rval = ((pPres->allWsW = wspCreateToggleButton (pPres->formW, 
457                   ((unsigned char *)GETMESSAGE(52, 4, "All Workspaces")))) 
458                 != NULL);
459         XtAddCallback (pPres->allWsW, XmNvalueChangedCallback, 
460                         (XtCallbackProc)wspAllWsCB, (XtPointer)pSD); 
461     }
462
463     if (rval)
464     {
465         rval = ((pPres->sepW = wspCreateSeparator (pPres->formW)) != NULL);
466     }
467
468     if (rval)
469     {
470 #ifndef NO_MESSAGE_CATALOG
471         rval = ((pPres->OkW = 
472                  wspCreatePushButton (pPres->formW, "ok", wmGD.okLabel))
473                         != NULL);
474 #else
475         tmpXmString = XmStringCreateLocalized ("OK");
476         rval = ((pPres->OkW = 
477                  wspCreatePushButton (pPres->formW, "ok", tmpXmString))
478                         != NULL);
479         XmStringFree(tmpXmString);
480 #endif
481
482         /* set the default action */
483         n = 0;
484         XtSetArg (args[n], XmNdefaultButton, pPres->OkW);    n++;
485         XtSetValues (pPres->formW, args, n);
486
487         XtAddCallback (pPres->OkW, XmNactivateCallback, 
488                 (XtCallbackProc) wspOkCB, (XtPointer)pSD); 
489     }
490
491     if (rval)
492     {
493 #ifndef NO_MESSAGE_CATALOG
494         rval = ((pPres->CancelW = wspCreatePushButton (pPres->formW, 
495                         "cancel", wmGD.cancelLabel)) != NULL);
496 #else
497         tmpXmString = XmStringCreateLocalized ("Cancel");
498         rval = ((pPres->CancelW = 
499                 wspCreatePushButton (pPres->formW, "cancel", tmpXmString))
500                         != NULL);
501         XmStringFree(tmpXmString);
502 #endif
503         XtAddCallback (pPres->CancelW, XmNactivateCallback, 
504                 (XtCallbackProc) wspCancelCB, (XtPointer)pSD); 
505
506         /* set the cancel button (for KCancel) */
507         n = 0;
508         XtSetArg (args[n], XmNcancelButton, pPres->CancelW);    n++;
509         XtSetValues (pPres->formW, args, n);
510     }
511
512     if (rval)
513     {
514 #ifndef NO_MESSAGE_CATALOG
515         rval = ((pPres->HelpW = 
516                 wspCreatePushButton (pPres->formW, "help", wmGD.helpLabel))
517                         != NULL);
518 #else
519         tmpXmString = XmStringCreateLocalized ("Help");
520         rval = ((pPres->HelpW = 
521                 wspCreatePushButton (pPres->formW,  "help", tmpXmString))
522                         != NULL);
523         XmStringFree(tmpXmString);
524 #endif
525
526 #ifdef  PANELIST
527         XtAddCallback (pPres->HelpW, XmNactivateCallback, 
528                        WmDtWmTopicHelpCB, 
529                        WM_DT_WSPRESENCE_TOPIC);
530 #else /* PANELIST */
531         XtAddCallback (pPres->HelpW, XmNactivateCallback, 
532                 (XtCallbackProc) wspHelpCB, (XtPointer)pSD); 
533 #endif /* PANELIST */
534     }
535
536     return(rval);
537 } /* END OF FUNCTION   */
538
539
540 \f
541 /*************************************<->*************************************
542  *
543  *  Widget
544  *  wspCreateShell (pSD)
545  *
546  *
547  *  Description:
548  *  -----------
549  *  Creates the shell widget for the workspace presence dialog
550  *
551  *
552  *  Inputs:
553  *  ------
554  *  psD  =  pointer to screen data
555  * 
556  *  Outputs:
557  *  -------
558  *  Return = shell widget created
559  *
560  ******************************<->***********************************/
561 static Widget 
562 wspCreateShell(
563         WmScreenData *pSD )
564 {
565     Arg setArgs[20];
566     int i;
567     Widget shellW;
568
569     /*
570      * Create top level shell for workspace presence dialog
571      */
572
573     i=0;
574
575     XtSetArg (setArgs[i], XmNallowShellResize, (XtArgVal)True); i++; 
576     
577     XtSetArg (setArgs[i], XmNborderWidth, (XtArgVal)0);         i++; 
578
579     XtSetArg (setArgs[i], XmNkeyboardFocusPolicy, 
580         (XtArgVal)XmEXPLICIT);                                  i++;
581
582     XtSetArg (setArgs[i], XmNmappedWhenManaged, 
583         (XtArgVal)False);                                       i++;
584
585     XtSetArg (setArgs[i], XmNmwmFunctions, 
586         PRESENCE_BOX_FUNCTIONS);                                i++;
587
588     XtSetArg (setArgs[i], XmNmwmDecorations, 
589         (MWM_DECOR_TITLE|MWM_DECOR_BORDER));    i++;
590
591     XtSetArg (setArgs[i], XmNdepth, 
592         (XtArgVal) DefaultDepth (DISPLAY1, pSD->screen));       i++;
593
594     XtSetArg (setArgs[i], XmNscreen, (XtArgVal) 
595         ScreenOfDisplay (DISPLAY1, pSD->screen));               i++;
596
597     XtSetArg (setArgs[i], XtNcolormap, 
598         (XtArgVal )DefaultColormap(DISPLAY1, pSD->screen));     i++;
599
600     shellW = (Widget) XtCreatePopupShell (WmNfeedback,
601                                         transientShellWidgetClass,
602                                         pSD->screenTopLevelW1,
603                                         (ArgList)setArgs, i);
604
605     return (shellW);
606
607 } /* END OF FUNCTION wspCreateShell */
608
609 \f
610 /*************************************<->*************************************
611  *
612  *  wspCreateManager (shellW)
613  *
614  *
615  *  Description:
616  *  -----------
617  *  Creates the manager widget for the workspace presence dialog
618  *
619  *  Inputs:
620  *  ------
621  * 
622  *  Outputs:
623  *  -------
624  *
625  *  Comments:
626  *  ---------
627  *  Creates a form widget
628  ******************************<->***********************************/
629 static Widget 
630 wspCreateManager(
631         Widget shellW )
632 {
633     Arg setArgs[20];
634     Widget formW;
635
636
637     /* !!! set colors? !!! */
638
639     formW = (Widget) XmCreateForm (shellW, "form", (ArgList) setArgs, 0);
640
641     XtAddCallback (formW, XmNhelpCallback,
642                    WmDtWmTopicHelpCB, WM_DT_WSPRESENCE_TOPIC);
643
644     XtManageChild (formW);
645
646     return (formW);
647 } /* END OF FUNCTION   */
648
649
650 \f
651 /*************************************<->*************************************
652  *
653  *  wspCreateLabel (mgrW, pchName, pchString)
654  *
655  *
656  *  Description:
657  *  -----------
658  *  Creates a label widget as a child of the passed in manager
659  *
660  *  Inputs:
661  *  ------
662  *  mgrW = manager widget (parent of this label)
663  *  pchName = name of the widget
664  *  pchString = string that is to be in label
665  * 
666  *  Outputs:
667  *  -------
668  *  Return = Widget created.
669  *
670  *  Comments:
671  *  ---------
672  ******************************<->***********************************/
673 static Widget 
674 wspCreateLabel(
675         Widget mgrW,
676         unsigned char *pchName,
677         unsigned char *pchString )
678 {
679     Arg setArgs[20];
680     int i;
681     Widget labelW;
682     XmString tmpXmString = (XmString)NULL;
683
684     i = 0;
685
686     if (!strcmp((char *)pchName, "window"))
687     {
688         if (windowLabelString != (XmString)NULL)
689             XmStringFree(windowLabelString);
690         if (iconLabelString != (XmString)NULL)
691             XmStringFree(iconLabelString);
692
693         windowLabelString = 
694             XmStringCreateLocalized ((char *)GETMESSAGE(52, 2, "Window: "));
695         /* 
696          * If we do this, USE the message catalog for iconLabelString 
697          * just as we do for windowLabelString !!! 
698          */
699         iconLabelString = 
700             XmStringCreateLocalized ((char *)GETMESSAGE(52, 6, "Icon: "));
701
702         XtSetArg (setArgs[i], XmNlabelString, windowLabelString );   i++;
703     }
704     else
705     {
706         tmpXmString = XmStringCreateLocalized ((char *)pchString);
707         XtSetArg (setArgs[i], XmNlabelString, tmpXmString);   i++;
708     }
709     
710     labelW = XmCreateLabelGadget (mgrW, (char *)pchName, setArgs, i);
711     XtManageChild (labelW);
712
713     if (tmpXmString != (XmString)NULL)
714         XmStringFree(tmpXmString);
715
716     return (labelW);
717 } /* END OF FUNCTION   */
718
719 \f
720 /*************************************<->*************************************
721  *
722  *  wspCreateSeparator (mgrW)
723  *
724  *
725  *  Description:
726  *  -----------
727  *  Creates a separator widget as a child of the passed in manager
728  *
729  *  Inputs:
730  *  ------
731  *  mgrW = manager widget (parent of this label)
732  * 
733  *  Outputs:
734  *  -------
735  *  Return = Widget created.
736  *
737  *  Comments:
738  *  ---------
739  ******************************<->***********************************/
740 static Widget 
741 wspCreateSeparator(
742         Widget mgrW )
743 {
744     Arg setArgs[10];
745     int i;
746     Widget sepW;
747
748     i = 0;
749
750     sepW = XmCreateSeparatorGadget (mgrW, "separator", setArgs, i);
751     XtManageChild (sepW);
752
753     return (sepW);
754 } /* END OF FUNCTION   */
755
756
757 \f
758 /*************************************<->*************************************
759  *
760  *  wspCreateWorkspaceList (mgrW, pPres, pSD)
761  *
762  *
763  *  Description:
764  *  -----------
765  *  Creates a list widget containing all the workspaces defined for a 
766  *  screen.
767  *
768  *  Inputs:
769  *  ------
770  *  mgrW = manager widget (parent of this child)
771  *  pPres = pointer to presence data
772  *  pSD = ptr to screen data
773  * 
774  *  Outputs:
775  *  -------
776  *  Return = widget created.
777  *
778  *  Comments:
779  *  ---------
780  ******************************<->***********************************/
781 static Widget 
782 wspCreateWorkspaceList(
783         Widget mgrW,
784         PtrWsPresenceData pPres,
785         WmScreenData *pSD )
786 {
787     Arg setArgs[20];
788     int i;
789     Widget listW;
790     int numVisible;
791
792 #define MIN_VISIBLE     6
793
794     /*
795      * Create the array of strings that will go into the list.
796      */
797     if (((pPres->ItemStrings = (XmStringTable) XtMalloc 
798                 (pSD->numWorkspaces * sizeof(XmString *))) == NULL) ||
799         ((pPres->ItemSelected = (Boolean *) XtMalloc 
800                 (pSD->numWorkspaces * sizeof(Boolean))) == NULL))
801     {
802         Warning (((char *)GETMESSAGE(52, 5, "Insufficient memory to create Occupy Workspace dialog.")));
803         return (NULL);
804     }
805
806     pPres->numWorkspaces = pSD->numWorkspaces;
807
808     for (i = 0; i < pSD->numWorkspaces; i++)
809     {
810         pPres->ItemStrings[i] = XmStringCopy (pSD->pWS[i].title);
811
812         if (pSD->pWS[i].id == pSD->pActiveWS->id)
813         {
814             pPres->currentWsItem = 1+i;
815         }
816     }
817
818
819     /* 
820      * Create the widget
821      */
822     i = 0;
823
824     XtSetArg (setArgs[i], XmNitemCount, pSD->numWorkspaces);    i++;
825
826     XtSetArg (setArgs[i], XmNitems, pPres->ItemStrings);        i++;
827
828     XtSetArg (setArgs[i], XmNselectionPolicy, XmEXTENDED_SELECT); i++;
829
830     XtSetArg (setArgs[i], XmNlistSizePolicy, XmRESIZE_IF_POSSIBLE); i++;
831
832     listW = XmCreateScrolledList (mgrW, "list", setArgs, i);
833     XtManageChild (listW);
834
835     if (pPres->pCDforClient)
836     {
837         /*
838          * Highlight the workspaces this client resides in
839          */
840         for (i = 0; i < pPres->pCDforClient->pSD->numWorkspaces; i++)
841         {
842             if (ClientInWorkspace (&pPres->pCDforClient->pSD->pWS[i], 
843                                         pPres->pCDforClient))
844             {
845                 XmListSelectPos (listW, i+1, TRUE);
846                 pPres->ItemSelected[i] = True;
847             }
848             else
849             {
850                 pPres->ItemSelected[i] = False;
851             }
852         }
853     }
854
855     /*
856      * Insure a minimum number are visible.
857      */
858     i = 0;
859     XtSetArg (setArgs[i], XmNvisibleItemCount, &numVisible);    i++;
860     XtGetValues (listW, setArgs, i);
861
862     if (numVisible < MIN_VISIBLE)
863     {
864         i = 0;
865         XtSetArg (setArgs[i], XmNvisibleItemCount, MIN_VISIBLE);i++;
866         XtSetValues (listW, setArgs, i);
867     }
868
869     XtAddCallback (listW, XmNextendedSelectionCallback,
870                 (XtCallbackProc) wspExtendedSelectCB, (XtPointer)pSD);
871     /* Handle the double-click just like if the Ok button was pressed */
872     XtAddCallback (listW, XmNdefaultActionCallback,
873                 (XtCallbackProc) wspOkCB, (XtPointer)pSD); 
874
875
876     return (listW);
877 } /* END OF FUNCTION   */
878
879 \f
880 /*************************************<->*************************************
881  *
882  *  wspUpdateWorkspaceList (pPres)
883  *
884  *
885  *  Description:
886  *  -----------
887  *  Updates the list widget containing all the workspaces.
888  *  Sets the ones for this client.
889  *
890  *  Inputs:
891  *  ------
892  *  pPres = ptr to presence dialog data
893  * 
894  *  Outputs:
895  *  -------
896  *  none
897  *
898  *  Comments:
899  *  ---------
900  ******************************<->***********************************/
901 static void 
902 wspUpdateWorkspaceList(
903         PtrWsPresenceData pPres )
904 {
905     int n;
906     XmString xmsTmp, *pxmsSelected;
907     WmScreenData *pSD;
908     Arg args[5];
909     int wsnum, numSelected;
910
911     /* 
912      * Update the list of workspaces to -- one may have been
913      * renamed since the last time we were up.
914      */
915     pSD = pPres->pCDforClient->pSD;
916     for (wsnum = 0; wsnum < pSD->numWorkspaces; wsnum++)
917     {
918         xmsTmp = XmStringCopy (pSD->pWS[wsnum].title);
919
920         if (!XmStringCompare (xmsTmp, pPres->ItemStrings[wsnum]))
921         {
922             /* 
923              * Replace the string in our local list
924              */
925             XmStringFree (pPres->ItemStrings[wsnum]);
926             pPres->ItemStrings[wsnum] = xmsTmp;
927
928             /* 
929              * Replace the item in the scrolled list.
930              */
931             XmListDeletePos (pPres->workspaceListW, 1+wsnum);
932             XmListAddItem (pPres->workspaceListW, xmsTmp, 1+wsnum);
933         }
934         else
935         {
936             XmStringFree (xmsTmp);
937         }
938     }
939
940     /*
941      * Highlight the workspaces this client resides in
942      */
943     XmListDeselectAllItems (pPres->workspaceListW);
944     pxmsSelected = (XmString *) 
945       XtMalloc (pPres->pCDforClient->pSD->numWorkspaces * sizeof (XmString));
946     numSelected = 0;
947     for (wsnum = 0; wsnum < pPres->pCDforClient->pSD->numWorkspaces; wsnum++)
948     {
949         if (ClientInWorkspace (&pPres->pCDforClient->pSD->pWS[wsnum], 
950             pPres->pCDforClient))
951         {
952             pxmsSelected[numSelected++] = pPres->ItemStrings[wsnum];
953             pPres->ItemSelected[wsnum] = True;
954         }
955         else
956         {
957             pPres->ItemSelected[wsnum] = False;
958             pPres->pCDforClient->putInAll = False;
959         }
960
961         if (pPres->pCDforClient->pSD->pActiveWS->id ==
962                         pPres->pCDforClient->pSD->pWS[wsnum].id)
963         {
964             /* save item number of current workspace */
965             pPres->currentWsItem = 1+wsnum;
966         }
967     }
968
969     /* set the selected items */
970     n = 0;
971     XtSetArg (args[n], XmNselectedItems, pxmsSelected);         n++;
972     XtSetArg (args[n], XmNselectedItemCount, numSelected);      n++;
973     XtSetValues (pPres->workspaceListW, args, n);
974
975     /* set state of all workspaces button */
976     n = 0;
977     XtSetArg (args[n], XmNset, pPres->pCDforClient->putInAll);  n++;
978     XtSetValues (pPres->allWsW, args, n);
979
980     /* set name of window we're popped up for */
981     wspSetWindowName (pPres);
982
983     XtFree ((char *) pxmsSelected);
984     
985 } /* END OF FUNCTION   */
986
987 \f
988 /*************************************<->*************************************
989  *
990  *  wspCreateToggleButton (mgrW, pch)
991  *
992  *
993  *  Description:
994  *  -----------
995  *  Creates a toggle button as a child of mgrW with the string pch.
996  *
997  *  Inputs:
998  *  ------
999  *  mgrW = parent widget
1000  *  pch  = string to use for toggle button
1001  * 
1002  *  Outputs:
1003  *  -------
1004  *  Return = widget created
1005  *
1006  *  Comments:
1007  *  ---------
1008  ******************************<->***********************************/
1009 static Widget 
1010 wspCreateToggleButton(
1011         Widget mgrW,
1012         unsigned char *pch )
1013 {
1014     Arg setArgs[20];
1015     int i;
1016     Widget toggleW;
1017     XmString labelString;
1018
1019     i = 0;
1020
1021     labelString = XmStringCreateLocalized ((char *)pch);
1022     XtSetArg (setArgs[i], XmNlabelString, labelString);   i++;
1023
1024     toggleW = XmCreateToggleButton (mgrW, (char *)pch, setArgs, i);
1025
1026     XmStringFree(labelString);
1027
1028     XtManageChild (toggleW);
1029
1030     return (toggleW);
1031
1032 } /* END OF FUNCTION wspCreateToggleButton  */
1033
1034 \f
1035 /*************************************<->*************************************
1036  *
1037  *  wspCreatePushButton (mgrW, label)
1038  *
1039  *
1040  *  Description:
1041  *  -----------
1042  *  Creates a push button as a child of mgrW with the string pch.
1043  *
1044  *  Inputs:
1045  *  ------
1046  *  mgrW = parent widget
1047  *  label  = XmString to use for button label
1048  * 
1049  *  Outputs:
1050  *  -------
1051  *  Return = widget created
1052  *
1053  *  Comments:
1054  *  ---------
1055  ******************************<->***********************************/
1056 static Widget 
1057 wspCreatePushButton(
1058         Widget mgrW,
1059         char *name,
1060         XmString label )
1061
1062 {
1063     Arg setArgs[20];
1064     int i;
1065     Widget pushW;
1066
1067     i = 0;
1068
1069     XtSetArg (setArgs[i], XmNlabelString, label);               i++;
1070
1071     pushW = (Widget) XmCreatePushButton (mgrW, name, setArgs, i);
1072
1073     XtManageChild (pushW);
1074
1075     return (pushW);
1076
1077 } /* END OF FUNCTION wspCreatePushButton */
1078
1079 \f
1080 /*************************************<->*************************************
1081  *
1082  *  wspSetPosition (pPres)
1083  *
1084  *
1085  *  Description:
1086  *  -----------
1087  *  Sets the position of the workspace presence dialog
1088  *
1089  *  Inputs:
1090  *  ------
1091  *  pPres = pointer to workspace presence data
1092  *
1093  *  Outputs:
1094  *  --------
1095  * 
1096  ******************************<->***********************************/
1097 static void 
1098 wspSetPosition(
1099         PtrWsPresenceData pPres )
1100 {
1101     WmScreenData *pSD = pPres->pCDforClient->pSD;
1102     Arg args[10];
1103     int n;
1104     XFontStruct *font;
1105     Dimension height;
1106     int x, y;
1107
1108     /*
1109      * Get size of this dialog
1110      */
1111     n = 0;
1112     XtSetArg (args[n], XmNheight, &height);             n++;
1113     XtGetValues (pPres->shellW, args, n);
1114
1115     if (wmGD.positionIsFrame)
1116     {
1117         if (pSD->decoupleTitleAppearance)
1118         {
1119             font = pSD->clientTitleAppearance.font;
1120         }
1121         else
1122         {
1123             font = pSD->clientAppearance.font;
1124         }
1125
1126         height += TEXT_HEIGHT(font) + (2 * pSD->frameBorderWidth);
1127     }
1128
1129
1130     /* 
1131      * set position of dialog relative to client window 
1132      * (use system menu position)
1133      * set this dialog to be transient for the client
1134      * for which it is posted.
1135      */
1136     GetSystemMenuPosition (pPres->pCDforClient, 
1137                             &x, &y, height,
1138                             pPres->contextForClient);
1139
1140     n = 0;
1141     XtSetArg (args[n], XmNx, x);                                n++;
1142     XtSetArg (args[n], XmNy, y);                                n++;
1143     XtSetArg (args[n], XmNtransientFor, NULL);                  n++;
1144     if (pPres->contextForClient != F_CONTEXT_ICON)
1145     {
1146         XtSetArg (args[n], XmNwindowGroup, pPres->pCDforClient->client); n++;
1147     }
1148     else if (pSD->useIconBox && P_ICON_BOX(pPres->pCDforClient))
1149     {
1150         XtSetArg (args[n], XmNwindowGroup, 
1151                   P_ICON_BOX(pPres->pCDforClient)->pCD_iconBox->client); n++;
1152     }
1153     else
1154     {
1155         XtSetArg (args[n], XmNwindowGroup, 0); n++;
1156     }
1157     XtSetArg (args[n], XmNwaitForWm, False);                    n++;
1158
1159     XtSetValues (pPres->shellW, args, n);
1160
1161 } /* END OF FUNCTION wspSetPosition */
1162
1163 \f
1164 /*************************************<->*************************************
1165  *
1166  *  wspCharWidth (xmfl)
1167  *
1168  *
1169  *  Description:
1170  *  -----------
1171  *  Returns the max logical character width for this fontList
1172  *
1173  *
1174  *  Inputs:
1175  *  ------
1176  *  xmfl  -  XmFontList
1177  * 
1178  *  Returns:
1179  *  -------
1180  *  max logical character width
1181  *
1182  *  Comments:
1183  *  ---------
1184  ******************************<->***********************************/
1185 static Dimension
1186 wspCharWidth(
1187         XmFontList xmfl )
1188 {
1189     XmFontContext       fc;
1190     XmFontListEntry     entry;
1191     Dimension           dWidth, dTmpWidth;
1192     XtPointer           pFont;
1193     XmFontType          type;
1194     XFontSetExtents     *pExtents;
1195
1196     XmFontListInitFontContext ( &fc, xmfl);
1197
1198     dWidth = 0;
1199
1200     entry = XmFontListNextEntry (fc);
1201     while (entry)
1202     {
1203         pFont = XmFontListEntryGetFont (entry, &type);
1204
1205         switch (type)
1206         {
1207             case XmFONT_IS_FONT:
1208                 dTmpWidth = ((XFontStruct *)pFont)->max_bounds.rbearing -
1209                             ((XFontStruct *)pFont)->min_bounds.lbearing;
1210                 break;
1211
1212             case XmFONT_IS_FONTSET:
1213                 pExtents = XExtentsOfFontSet ((XFontSet) pFont);
1214                 dTmpWidth = pExtents->max_logical_extent.width;
1215                 break;
1216
1217             default:
1218                 dTmpWidth = 0;
1219                 break;
1220         }
1221
1222         if (dTmpWidth > dWidth)
1223             dWidth = dTmpWidth;
1224
1225         entry = XmFontListNextEntry (fc);
1226     }
1227
1228     XmFontListFreeFontContext (fc);
1229
1230     return (dWidth);
1231 }
1232
1233 \f
1234 /*************************************<->*************************************
1235  *
1236  *  wspLayout (pPres)
1237  *
1238  *
1239  *  Description:
1240  *  -----------
1241  *  Lays out the workspace presence dialog
1242  *
1243  *
1244  *  Inputs:
1245  *  ------
1246  *  pPres = pointer to workspace presence data
1247  * 
1248  *  Outputs:
1249  *  -------
1250  *  none
1251  *
1252  *  Comments:
1253  *  ---------
1254  ******************************<->***********************************/
1255 static void 
1256 wspLayout(
1257         PtrWsPresenceData pPres )
1258 {
1259     Arg args[20];
1260     int n;
1261
1262 #define SEP_OFFSET      10
1263 #define IW_OFFSET_1     8
1264 #define IW_OFFSET_0     4
1265
1266
1267     n = 0;
1268     XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION);    n++;
1269     XtSetArg (args[n], XmNtopPosition, 5);                      n++;
1270     XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);       n++;
1271     XtSetArg (args[n], XmNleftOffset, 5);                       n++;
1272     XtSetArg (args[n], XmNrightAttachment, XmATTACH_NONE);      n++;
1273     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_NONE);     n++;
1274     XtSetValues (pPres->windowLabelW, args, n);
1275
1276     n = 0;
1277     XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);      n++;
1278     XtSetArg (args[n], XmNtopWidget, pPres->windowLabelW);      n++;
1279     XtSetArg (args[n], XmNtopOffset, IW_OFFSET_0);              n++;
1280     XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);       n++;
1281     XtSetArg (args[n], XmNleftOffset, 5);                       n++;
1282     XtSetArg (args[n], XmNrightAttachment, XmATTACH_NONE);      n++;
1283     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_NONE);     n++;
1284     XtSetArg (args[n], XmNbottomOffset, 0);                     n++;
1285     XtSetValues (pPres->workspaceLabelW, args, n);
1286
1287     n = 0;
1288     XtSetArg (args[n], XmNtopAttachment, XmATTACH_POSITION);    n++;
1289     XtSetArg (args[n], XmNtopPosition, 5);                      n++;
1290     XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET);     n++;
1291     XtSetArg (args[n], XmNleftWidget, pPres->workspaceLabelW);  n++;
1292     XtSetArg (args[n], XmNleftOffset, 5);                       n++;
1293     XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);      n++;
1294     XtSetArg (args[n], XmNrightOffset, 5);                      n++;
1295     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_NONE);     n++;
1296     XtSetArg (args[n], XmNbottomOffset, 0);                     n++;
1297     XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING);    n++;
1298     XtSetValues (pPres->windowNameW, args, n);
1299
1300     n = 0;
1301     XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);      n++;
1302     XtSetArg (args[n], XmNtopWidget, pPres->windowNameW);       n++;
1303     XtSetArg (args[n], XmNtopOffset, IW_OFFSET_0);              n++;
1304     XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET);     n++;
1305     XtSetArg (args[n], XmNleftWidget, pPres->workspaceLabelW);  n++;
1306     XtSetArg (args[n], XmNleftOffset, 5);                       n++;
1307     XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);      n++;
1308     XtSetArg (args[n], XmNrightOffset, 5);                      n++;
1309     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_NONE);     n++;
1310     XtSetArg (args[n], XmNbottomOffset, 0);                     n++;
1311     XtSetValues (pPres->workspaceScrolledListW, args, n);
1312
1313     n = 0;
1314     XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);      n++;
1315     XtSetArg (args[n], XmNtopWidget, pPres->workspaceScrolledListW);    n++;
1316     XtSetArg (args[n], XmNtopOffset, IW_OFFSET_1);              n++;
1317     XtSetArg (args[n], XmNleftAttachment, XmATTACH_WIDGET);     n++;
1318     XtSetArg (args[n], XmNleftWidget, pPres->workspaceLabelW);  n++;
1319     XtSetArg (args[n], XmNleftOffset, 5);                       n++;
1320     XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);      n++;
1321     XtSetArg (args[n], XmNrightOffset, 5);                      n++;
1322     XtSetArg (args[n], XmNalignment, XmALIGNMENT_BEGINNING);    n++;
1323     XtSetArg (args[n], XmNmarginRight, 5);                      n++;
1324     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_NONE);     n++;
1325     XtSetArg (args[n], XmNbottomOffset, 0);                     n++;
1326     XtSetValues (pPres->allWsW, args, n);
1327
1328     n = 0;
1329     XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);      n++;
1330     XtSetArg (args[n], XmNtopWidget, pPres->allWsW);            n++;
1331     XtSetArg (args[n], XmNtopOffset, SEP_OFFSET);               n++;
1332     XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM);       n++;
1333     XtSetArg (args[n], XmNleftOffset, 0);                       n++;
1334     XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM);      n++;
1335     XtSetArg (args[n], XmNrightOffset, 0);                      n++;
1336     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_NONE);     n++;
1337     XtSetArg (args[n], XmNbottomOffset, 0);                     n++;
1338     XtSetValues (pPres->sepW, args, n);
1339
1340     n = 0;
1341     XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);      n++;
1342     XtSetArg (args[n], XmNtopWidget, pPres->sepW);              n++;
1343     XtSetArg (args[n], XmNtopOffset, SEP_OFFSET);               n++;
1344     XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION);   n++;
1345     XtSetArg (args[n], XmNleftPosition, 5);                     n++;
1346     XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION);  n++;
1347     XtSetArg (args[n], XmNrightPosition, 30);                   n++;
1348     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
1349     XtSetArg (args[n], XmNbottomPosition, 95);                  n++;
1350     XtSetValues (pPres->OkW, args, n);
1351
1352     n = 0;
1353     XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);      n++;
1354     XtSetArg (args[n], XmNtopWidget, pPres->sepW);              n++;
1355     XtSetArg (args[n], XmNtopOffset, SEP_OFFSET);               n++;
1356     XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION);   n++;
1357     XtSetArg (args[n], XmNleftPosition, 36);                    n++;
1358     XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION);  n++;
1359     XtSetArg (args[n], XmNrightPosition, 66);                   n++;
1360     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
1361     XtSetArg (args[n], XmNbottomPosition, 95);                  n++;
1362     XtSetValues (pPres->CancelW, args, n);
1363
1364     n = 0;
1365     XtSetArg (args[n], XmNtopAttachment, XmATTACH_WIDGET);      n++;
1366     XtSetArg (args[n], XmNtopWidget, pPres->sepW);              n++;
1367     XtSetArg (args[n], XmNtopOffset, SEP_OFFSET);               n++;
1368     XtSetArg (args[n], XmNleftAttachment, XmATTACH_POSITION);   n++;
1369     XtSetArg (args[n], XmNleftPosition, 71);                    n++;
1370     XtSetArg (args[n], XmNrightAttachment, XmATTACH_POSITION);  n++;
1371     XtSetArg (args[n], XmNrightPosition, 95);                   n++;
1372     XtSetArg (args[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
1373     XtSetArg (args[n], XmNbottomPosition, 95);                  n++;
1374     XtSetValues (pPres->HelpW, args, n);
1375 } /* END OF FUNCTION   */
1376
1377
1378 \f
1379 /*************************************<->*************************************
1380  *
1381  *  static void
1382  *  wspOkCB (w, client_data, call_data)
1383  *
1384  *
1385  *  Description:
1386  *  -----------
1387  *  OK callback.
1388  *
1389  *
1390  *  Inputs:
1391  *  ------
1392  *  pSD = pointer to screen data
1393  *
1394  * 
1395  *  Outputs:
1396  *  -------
1397  *  None.
1398  *
1399  *
1400  *  Comments:
1401  *  --------
1402  *  None.
1403  * 
1404  *************************************<->***********************************/
1405
1406 static void 
1407 wspOkCB(
1408         Widget buttonW,
1409         WmScreenData *pSD,
1410         XtPointer call_data )
1411 {
1412     Arg args[20];
1413     int n, j;
1414     int selectedItemCount;
1415     XmStringTable selectedItems;
1416     PtrWsPresenceData pPres = &pSD->presence;
1417     Boolean bAllSelected;
1418
1419
1420     /* find the selected workspaces */
1421     n = 0;
1422     XtSetArg (args[n], XmNselectedItemCount, &selectedItemCount); n++;
1423     XtSetArg (args[n], XmNselectedItems, &selectedItems); n++;
1424     XtGetValues (pPres->workspaceListW, args, n);
1425
1426     /* find the state of all workspaces button */
1427     n = 0;
1428     XtSetArg (args[n], XmNset, &bAllSelected);  n++;
1429     XtGetValues (pPres->allWsW, args, n);
1430
1431     if (bAllSelected)
1432     {
1433         F_AddToAllWorkspaces(NULL, pPres->pCDforClient, NULL);
1434     }
1435     else if (selectedItemCount)
1436     {
1437         for (n = 0; n < pSD->numWorkspaces; n++)
1438         {
1439             pPres->ItemSelected[n] = False;
1440             for (j = 0; j < selectedItemCount; j++)
1441             {
1442                 if (XmStringCompare (selectedItems[j], 
1443                         pPres->ItemStrings[n]))
1444                 {
1445                     pPres->ItemSelected[n] = True;
1446                 }
1447             }
1448
1449             if (!pPres->ItemSelected[n]  &&
1450                 ClientInWorkspace (&pSD->pWS[n], pPres->pCDforClient))
1451             {
1452                 RemoveClientFromWorkspaces (pPres->pCDforClient, 
1453                     &pSD->pWS[n].id, 1);
1454             }
1455
1456             if (pPres->ItemSelected[n] &&
1457                 !ClientInWorkspace (&pSD->pWS[n], pPres->pCDforClient))
1458             {
1459                 AddClientToWorkspaces (pPres->pCDforClient, 
1460                         &pSD->pWS[n].id, 1);
1461             }
1462         }
1463     }
1464
1465     /* withdraw the dialog */
1466     wspCancelCB (buttonW, (XtPointer)pSD, call_data);
1467 } /* END OF FUNCTION   */
1468
1469 \f
1470 /*************************************<->*************************************
1471  *
1472  *  static void
1473  *  wspHelpCB (w, client_data, call_data)
1474  *
1475  *
1476  *  Description:
1477  *  -----------
1478  *  Help callback.
1479  *
1480  *
1481  *  Inputs:
1482  *  ------
1483  *  None.
1484  *
1485  * 
1486  *  Outputs:
1487  *  -------
1488  *  None.
1489  *
1490  *
1491  *  Comments:
1492  *  --------
1493  *  None.
1494  * 
1495  *************************************<->***********************************/
1496
1497 #ifndef PANELIST
1498 static void 
1499 wspHelpCB(
1500         Widget buttonW,
1501         XtPointer client_data,
1502         XtPointer call_data )
1503 {
1504
1505     DtHelpOnTopic (XtParent(buttonW), "vw_pres");
1506 } /* END OF FUNCTION   */
1507 #endif  /* PANELIST */
1508 \f
1509 /*************************************<->*************************************
1510  *
1511  *  static void
1512  *  wspAllWsCB (w, client_data, call_data)
1513  *
1514  *
1515  *  Description:
1516  *  -----------
1517  *  All Workspace toggle button callback.
1518  *
1519  *
1520  *  Inputs:
1521  *  ------
1522  *  None.
1523  *
1524  * 
1525  *  Outputs:
1526  *  -------
1527  *  None.
1528  *
1529  *
1530  *  Comments:
1531  *  --------
1532  *  None.
1533  * 
1534  *************************************<->***********************************/
1535
1536 static void 
1537 wspAllWsCB(
1538         Widget buttonW,
1539         WmScreenData *pSD,
1540         XmToggleButtonCallbackStruct *xmTbcs )
1541 {
1542     PtrWsPresenceData pPres = &pSD->presence;
1543     int wsnum;
1544     XmString *pxmsSelected;
1545     Arg args[5];
1546     int n;
1547
1548     if (xmTbcs->reason == XmCR_VALUE_CHANGED)
1549     {
1550         if (xmTbcs->set)
1551         {
1552             pxmsSelected = (XmString *)
1553                 XtMalloc (pSD->numWorkspaces * sizeof (XmString));
1554
1555             for (wsnum = 0; wsnum < pSD->numWorkspaces; wsnum++)
1556             {
1557                 pxmsSelected[wsnum] = pPres->ItemStrings[wsnum];
1558             }
1559
1560             /* set the selected items */
1561             n = 0;
1562             XtSetArg (args[n], XmNselectedItems, pxmsSelected);         n++;
1563             XtSetArg (args[n], XmNselectedItemCount, pSD->numWorkspaces); n++;
1564             XtSetValues (pPres->workspaceListW, args, n);
1565
1566             XtFree ((char *) pxmsSelected);
1567         }
1568         else
1569         {
1570             /* select current workspace */
1571             XmListDeselectAllItems (pPres->workspaceListW);
1572             XmListSelectPos (pPres->workspaceListW, pPres->currentWsItem, TRUE);
1573         }
1574     }
1575 } /* END OF FUNCTION   */
1576
1577
1578
1579 \f
1580 /*************************************<->*************************************
1581  *
1582  *  static void
1583  *  wspExtendedSelectCB (w, client_data, cb)
1584  *
1585  *
1586  *  Description:
1587  *  -----------
1588  *  Cancel callback.
1589  *
1590  *
1591  *  Inputs:
1592  *  ------
1593  *  None.
1594  *
1595  * 
1596  *  Outputs:
1597  *  -------
1598  *  None.
1599  *
1600  *
1601  *  Comments:
1602  *  --------
1603  *  None.
1604  * 
1605  *************************************<->***********************************/
1606
1607 static void 
1608 wspExtendedSelectCB(
1609         Widget w,
1610         XtPointer client_data,
1611         XmListCallbackStruct *cb )
1612 {
1613     WmScreenData *pSD = (WmScreenData *) client_data;
1614     PtrWsPresenceData pPres = &pSD->presence;
1615     int n;
1616     Arg args[5];
1617
1618     if (cb->reason == XmCR_EXTENDED_SELECT)
1619     {
1620         if ((cb->selected_item_count < pSD->numWorkspaces) &&
1621             (cb->event != None))
1622         {
1623             n = 0;
1624             XtSetArg (args[n], XmNset, False);  n++;
1625             XtSetValues (pPres->allWsW, args, n);
1626         }
1627     }
1628
1629 } /* END OF FUNCTION wspExtendedSelectCB */
1630
1631
1632 \f
1633 /*************************************<->*************************************
1634  *
1635  *  static void
1636  *  wspCancelCB (w, client_data, call_data)
1637  *
1638  *
1639  *  Description:
1640  *  -----------
1641  *  Cancel callback.
1642  *
1643  *
1644  *  Inputs:
1645  *  ------
1646  *  None.
1647  *
1648  * 
1649  *  Outputs:
1650  *  -------
1651  *  None.
1652  *
1653  *
1654  *  Comments:
1655  *  --------
1656  *  None.
1657  * 
1658  *************************************<->***********************************/
1659
1660 static void 
1661 wspCancelCB(
1662         Widget buttonW,
1663         XtPointer client_data,
1664         XtPointer call_data )
1665 {
1666     WmScreenData *pSD = (WmScreenData *) client_data;
1667
1668     XtPopdown (pSD->presence.shellW);
1669     pSD->presence.onScreen = False;
1670
1671 } /* END OF FUNCTION wspCancelCB */
1672
1673 \f
1674 /*************************************<->*************************************
1675  *
1676  * GetPresenceBoxMenuItems (pSD)
1677  *
1678  *
1679  *  Description:
1680  *  -----------
1681  *  XXDescription ...
1682  * 
1683  *************************************<->***********************************/
1684
1685 MenuItem * 
1686 GetPresenceBoxMenuItems(
1687         WmScreenData *pSD )
1688 {
1689
1690     return(NULL);
1691
1692 } /* END OF FUNCTION GetPresenceBoxMenuItems */
1693
1694 \f
1695 /*************************************<->*************************************
1696  *
1697  * UpdatePresenceWorkspaces (pSD)
1698  *
1699  *
1700  *  Description:
1701  *  -----------
1702  *  Update the presence dialog when the number of workspaces changes.
1703  * 
1704  *************************************<->***********************************/
1705
1706 void
1707 UpdatePresenceWorkspaces(
1708         WmScreenData *pSD )
1709 {
1710     PtrWsPresenceData pPres = &pSD->presence;
1711     int wsnum;
1712     XmString xmsTmp;
1713
1714     if (pPres->shellW)
1715     {
1716         if (pPres->numWorkspaces < pSD->numWorkspaces)
1717         {
1718             if (((pPres->ItemStrings = (XmStringTable) XtRealloc 
1719                     ((char *)pPres->ItemStrings,
1720                     (pSD->numWorkspaces * sizeof(XmString *)))) == NULL) ||
1721                 ((pPres->ItemSelected = (Boolean *) XtRealloc 
1722                     ((char *)pPres->ItemSelected,
1723                     (pSD->numWorkspaces * sizeof(Boolean)))) == NULL))
1724             {
1725                 Warning (((char *)GETMESSAGE(52, 5, "Insufficient memory to create Occupy Workspace dialog.")));
1726                 pPres->shellW = NULL;
1727                 return;
1728             }
1729         }
1730
1731         /*
1732          * Replace the names in the dialog's list
1733          */
1734         for (wsnum = 0; wsnum < pPres->numWorkspaces; wsnum++)
1735         {
1736             if (wsnum < pSD->numWorkspaces)
1737             {
1738                 xmsTmp = XmStringCopy (pSD->pWS[wsnum].title);
1739
1740                 if (!XmStringCompare (xmsTmp, pPres->ItemStrings[wsnum]))
1741                 {
1742                     /* 
1743                      * Replace the string in our local list
1744                      */
1745                     XmStringFree (pPres->ItemStrings[wsnum]);
1746                     pPres->ItemStrings[wsnum] = xmsTmp;
1747
1748                     /* 
1749                      * Replace the item in the scrolled list.
1750                      */
1751                     XmListDeletePos (pPres->workspaceListW, 1+wsnum);
1752                     XmListAddItem (pPres->workspaceListW, xmsTmp, 1+wsnum);
1753                 }
1754                 else
1755                 {
1756                     XmStringFree (xmsTmp);
1757                 }
1758             }
1759             else
1760             {
1761                 /*
1762                  * Delete this workspace from the list
1763                  */
1764                 XmStringFree (pPres->ItemStrings[wsnum]);
1765                 pPres->ItemStrings[wsnum] = NULL;
1766                 XmListDeletePos (pPres->workspaceListW, 1+wsnum);
1767             }
1768         }
1769         for (; wsnum < pSD->numWorkspaces; wsnum++)
1770         {
1771             /*
1772              * Add these workspaces to the list.
1773              */
1774             xmsTmp = XmStringCopy (pSD->pWS[wsnum].title);
1775             pPres->ItemStrings[wsnum] = xmsTmp;
1776             XmListAddItem (pPres->workspaceListW, xmsTmp, 1+wsnum);
1777
1778             if (pPres->pCDforClient && 
1779                 (ClientInWorkspace (&pPres->pCDforClient->pSD->pWS[wsnum], 
1780                                         pPres->pCDforClient)))
1781             {
1782                 XmListSelectPos (pPres->workspaceListW, 1+wsnum, TRUE);
1783                 pPres->ItemSelected[wsnum] = True;
1784             }
1785             else
1786             {
1787                 pPres->ItemSelected[wsnum] = False;
1788             }
1789         }
1790
1791         pPres->numWorkspaces = pSD->numWorkspaces;
1792     }
1793
1794 } /* END OF FUNCTION UpdatePresenceWorkspaces */
1795
1796 /* DO NOT ADD ANYTHING AFTER THIS ENDIF */
1797 #endif /* WSM */
1798 /****************************   eof    ***************************/