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