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