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