Use C++ linker
[oweals/cde.git] / cde / programs / dtwm / WmProperty.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* 
24  * (c) Copyright 1989, 1990, 1991, 1992, 1993 OPEN SOFTWARE FOUNDATION, INC. 
25  * ALL RIGHTS RESERVED 
26 */ 
27 /* 
28  * Motif Release 1.2.3
29 */ 
30 #ifdef REV_INFO
31 #ifndef lint
32 static char rcsid[] = "$TOG: WmProperty.c /main/7 1997/12/02 10:00:00 bill $"
33 #endif
34 #endif
35 /*
36  * (c) Copyright 1987, 1988, 1989, 1990, 1993 HEWLETT-PACKARD COMPANY */
37
38 /*
39  * Included Files:
40  */
41
42 #include "WmGlobal.h"
43 #include "WmICCC.h"
44 #include <stdio.h>
45 #ifdef WSM
46 #include <Dt/WsmP.h>
47 #include <X11/Xatom.h>
48 #endif /* WSM */
49
50 /*
51  * include extern functions
52  */
53
54 #include "WmColormap.h"
55 #include "WmError.h"
56 #include "WmResParse.h"
57
58
59
60 /*
61  * Function Declarations:
62  */
63
64 #include "WmProperty.h"
65
66
67 /*
68  * Global Variables:
69  */
70
71 static SizeHints sizeHints;
72
73
74 \f
75 /*************************************<->*************************************
76  *
77  *  SizeHints *
78  *  GetNormalHints (pCD)
79  *
80  *
81  *  Description:
82  *  -----------
83  *  This function replaces the XGetNormalHints Xlib function.  This function
84  *  gets the information in the WM_NORMAL_HINTS property on the client window.
85  *  The property encoding can be any of the supported versions (R2, R3+).
86  *
87  *
88  *  Inputs:
89  *  ------
90  *  pCD = (client)
91  *
92  * 
93  *  Outputs:
94  *  -------
95  *  Return = A pointer to a filled out SizeHints structure is returned.
96  *           Default values are set if the WM_NORMAL_HINTS property could
97  *           not be retrieved.
98  *
99  *************************************<->***********************************/
100
101 SizeHints * 
102 GetNormalHints(
103         ClientData *pCD )
104
105 {
106     PropSizeHints *property = NULL;
107     Atom actualType;
108     int actualFormat;
109     unsigned long leftover;
110     unsigned long nitems;
111
112
113     /*
114      * Retrieve the property data.
115      *
116      *     ICCC_R2 version:  nitems = PROP_SIZE_HINTS_ELEMENTS - 3
117      *     ICCC_CURRENT version: nitems = PROP_SIZE_HINTS_ELEMENTS
118      */
119
120 #ifdef WSM
121     if ((!HasProperty (pCD, XA_WM_NORMAL_HINTS)) ||
122         ((Success != XGetWindowProperty (DISPLAY, pCD->client,
123                         XA_WM_NORMAL_HINTS, 0L, (long)PROP_SIZE_HINTS_ELEMENTS,
124                         False, XA_WM_SIZE_HINTS, &actualType, &actualFormat,
125                         &nitems, &leftover, (unsigned char **)&property)) ||
126           (actualType != XA_WM_SIZE_HINTS) ||
127           (nitems < (PROP_SIZE_HINTS_ELEMENTS - 3)) ||
128           (actualFormat != 32)))
129 #else /* WSM */
130     if ((Success != XGetWindowProperty (DISPLAY, pCD->client,
131                         XA_WM_NORMAL_HINTS, 0L, (long)PROP_SIZE_HINTS_ELEMENTS,
132                         False, XA_WM_SIZE_HINTS, &actualType, &actualFormat,
133                         &nitems, &leftover, (unsigned char **)&property)) ||
134          (actualType != XA_WM_SIZE_HINTS) ||
135          (nitems < (PROP_SIZE_HINTS_ELEMENTS - 3)) ||
136          (actualFormat != 32))
137 #endif /* WSM */
138     {
139         /*
140          * Indicate no property values were retrieved:
141          */
142
143         sizeHints.icccVersion = ICCC_UNKNOWN;
144         sizeHints.flags = 0;
145     }
146     else
147     {
148         /*
149          * Parse the hint values out of the property data:
150          */
151
152         sizeHints.flags = property->flags;
153         sizeHints.x = property->x;
154         sizeHints.y = property->y;
155         sizeHints.width = property->width;
156         sizeHints.height = property->height;
157         sizeHints.min_width = property->minWidth;
158         sizeHints.min_height = property->minHeight;
159         sizeHints.max_width = property->maxWidth;
160         sizeHints.max_height = property->maxHeight;
161         sizeHints.width_inc = property->widthInc;
162         sizeHints.height_inc = property->heightInc;
163         sizeHints.min_aspect.x = (int)property->minAspectX;
164         sizeHints.min_aspect.y = (int)property->minAspectY;
165         sizeHints.max_aspect.x = (int)property->maxAspectX;
166         sizeHints.max_aspect.y = (int)property->maxAspectY;
167
168
169         if (nitems == (PROP_SIZE_HINTS_ELEMENTS - 3))
170         {
171             /*
172              *  This is ICCC_R2.
173              */
174
175             sizeHints.icccVersion = ICCC_R2;
176         }
177         else
178         {
179             /*
180              *  This is ICCC_CURRENT.
181              */
182
183             sizeHints.icccVersion = ICCC_CURRENT;
184             sizeHints.base_width = property->baseWidth;
185             sizeHints.base_height = property->baseHeight;
186             sizeHints.win_gravity = property->winGravity;
187         }
188     }
189
190
191     /*
192      * Free the property data buffer:
193      */
194
195     if (property)
196     {
197         XFree ((char *)property);
198     }
199
200
201     /*
202      * Return the hints values:
203      */
204
205     return (&sizeHints);
206
207
208 } /* END OF FUNCTION GetNormalHints */
209
210
211 \f
212 /*************************************<->*************************************
213  *
214  *  ProcessWmProtocols (pCD)
215  *
216  *
217  *  Description:
218  *  -----------
219  *  This function reads and processes the WM_PROTOCOLS property that is
220  *  associated with a client window.
221  *
222  *  ICCC_COMPLIANT check added to allow older clients to work, for now...
223  *  eventually, this code should be removed.
224  *
225  *  Inputs:
226  *  ------
227  *  pCD = pointer to client data
228  *
229  * 
230  *  Outputs:
231  *  -------
232  *  pCD = (clientProtocols, clientProtocolCount, protocolFlags)
233  *
234  *************************************<->***********************************/
235
236 void ProcessWmProtocols (ClientData *pCD)
237 {
238     int rValue;
239     Atom *property = NULL;
240 #ifndef ICCC_COMPLIANT
241     Atom actualType;
242     int actualFormat;
243     unsigned long leftover;
244     unsigned long nitems;
245 #else
246     int nitems;
247 #endif /* ICCC_COMPLIANT */
248     int i;
249
250
251     if (pCD->clientProtocols)
252     {
253         XtFree ((char *)pCD->clientProtocols);
254         pCD->clientProtocols = NULL;
255     }
256     pCD->clientProtocolCount = 0;
257     pCD->protocolFlags = 0;
258
259
260     /*
261      * Read the WM_PROTOCOLS property.
262      */
263
264 #ifndef ICCC_COMPLIANT
265 #ifdef WSM
266     if (!HasProperty (pCD, wmGD.xa_WM_PROTOCOLS))
267         rValue = -1;
268     else
269 #endif /* WSM */
270     rValue = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_WM_PROTOCOLS, 0L,
271                  (long)MAX_CLIENT_PROTOCOL_COUNT, False, AnyPropertyType,
272                  &actualType, &actualFormat, &nitems, &leftover,
273                  (unsigned char **)&property);
274
275
276     if ((rValue != Success) || (actualType == None) || (actualFormat != 32))
277 #else
278 #ifdef WSM
279     if (!HasProperty (pCD, wmGD.xa_WM_PROTOCOLS))
280         rValue = -1;
281     else
282 #endif /* WSM */
283     rValue = XGetWMProtocols (DISPLAY, pCD->client, 
284                  (Atom **)&property, &nitems);
285
286     if (0 == rValue) 
287 #endif /* ICCC_COMPLIANT */
288     {
289         /*
290          * WM_PROTOCOLS does not exist or it is an invalid type or size.
291          */
292
293         pCD->clientProtocols = NULL;
294     }
295     else
296     {
297         if (!(pCD->clientProtocols = (Atom *)XtMalloc (nitems * sizeof (Atom))))
298         {
299             /* unable to allocate space */
300             Warning (((char *)GETMESSAGE(54, 1, "Insufficient memory for window management data")));
301         }
302         else
303         {
304             /*
305              * Save the protocols in the client data and look for predefined
306              * protocols.
307              */
308
309             pCD->clientProtocolCount = nitems;
310
311             for (i = 0; i < nitems; i++)
312             {
313                 pCD->clientProtocols[i] = property[i];
314                 if (property[i] == wmGD.xa_WM_SAVE_YOURSELF)
315                 {
316                     pCD->protocolFlags |= PROTOCOL_WM_SAVE_YOURSELF;
317                 }
318                 else if (property[i] == wmGD.xa_WM_TAKE_FOCUS)
319                 {
320                     pCD->protocolFlags |= PROTOCOL_WM_TAKE_FOCUS;
321                 }
322                 else if (property[i] == wmGD.xa_WM_DELETE_WINDOW)
323                 {
324                     pCD->protocolFlags |= PROTOCOL_WM_DELETE_WINDOW;
325                 }
326                 else if (property[i] == wmGD.xa_MWM_MESSAGES)
327                 {
328                     pCD->protocolFlags |= PROTOCOL_MWM_MESSAGES;
329                 }
330             }
331         }
332     }
333
334
335     if (property)
336     {
337         XFree ((char *)property);
338     }
339
340
341 } /* END OF FUNCTION ProcessWmProtocols */
342
343
344 \f
345 /*************************************<->*************************************
346  *
347  *  ProcessMwmMessages (pCD)
348  *
349  *
350  *  Description:
351  *  -----------
352  *  This function reads and processes the _MWM_MESSAGES property that is
353  *  associated with a client window.
354  *
355  *
356  *  Inputs:
357  *  ------
358  *  pCD = pointer to client data
359  *
360  * 
361  *  Outputs:
362  *  -------
363  *  pCD = (mwmMessagesCount, mwmMessages)
364  *
365  *************************************<->***********************************/
366
367 void ProcessMwmMessages (ClientData *pCD)
368 {
369     int rValue;
370     long *property = NULL;
371     Atom actualType;
372     int actualFormat;
373     unsigned long leftover;
374     unsigned long nitems;
375     int i;
376
377
378     if (pCD->mwmMessages)
379     {
380         XtFree ((char *)pCD->mwmMessages);
381         pCD->mwmMessages = NULL;
382     }
383     pCD->mwmMessagesCount = 0;
384
385
386     /*
387      * Read the _MWM_MESSAGES property.
388      */
389
390 #ifdef WSM
391     if (!HasProperty (pCD, wmGD.xa_MWM_MESSAGES))
392         rValue = ~Success;
393     else
394 #endif /* WSM */
395     rValue = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_MWM_MESSAGES, 0L,
396                  (long)MAX_MWM_MESSAGES_COUNT, False, AnyPropertyType,
397                  &actualType, &actualFormat, &nitems, &leftover,
398                  (unsigned char **)&property);
399
400
401     if ((rValue != Success) || (actualType == None) || (actualFormat != 32)
402         || (nitems == 0))
403     {
404         /*
405          * _MWM_MESSAGES does not exist or it is an invalid type.
406          */
407
408         pCD->mwmMessages = NULL;
409     }
410     else
411     {
412         if (!(pCD->mwmMessages = (long *)XtMalloc (nitems * sizeof (long))))
413         {
414             /* unable to allocate space */
415             Warning (((char *)GETMESSAGE(54, 2, "Insufficient memory for window management data")));
416         }
417         else
418         {
419             /*
420              * Save the protocols in the client data and look for predefined
421              * protocols.
422              */
423
424             pCD->mwmMessagesCount = nitems;
425
426             for (i = 0; i < nitems; i++)
427             {
428                 if ((pCD->mwmMessages[i] = property[i]) == wmGD.xa_MWM_OFFSET)
429                 {
430                     pCD->protocolFlags |= PROTOCOL_MWM_OFFSET;
431                 }
432             }
433         }
434     }
435
436
437     if (property)
438     {
439         XFree ((char *)property);
440     }
441
442
443 } /* END OF FUNCTION ProcessMwmMessages */
444
445
446 \f
447 /*************************************<->*************************************
448  *
449  *  SetMwmInfo (propWindow, flags, wmWindow)
450  *
451  *
452  *  Description:
453  *  -----------
454  *  This function sets up the _MOTIF_WM_INFO property on the specified (usually
455  *  the root) window.
456  *
457  *
458  *  Inputs:
459  *  ------
460  *  propWindow = window on which the _MOTIF_WM_INFO property is to be set
461  *
462  *  flags = motifWmInfo.flags value
463  *
464  *  wmWindow = motifWmInfo.wmWindow value
465  *
466  * 
467  *  Outputs:
468  *  -------
469  *  _MWM_INFO = this property is set on the specified window
470  *
471  *************************************<->***********************************/
472
473 void SetMwmInfo (Window propWindow, long flags, Window wmWindow)
474 {
475     PropMwmInfo property;
476
477
478     property.flags = flags;
479     property.wmWindow = wmWindow;
480
481     XChangeProperty (DISPLAY, propWindow, wmGD.xa_MWM_INFO, wmGD.xa_MWM_INFO,
482         32, PropModeReplace, (unsigned char *)&property,
483         PROP_MWM_INFO_ELEMENTS);
484
485 } /* END OF FUNCTION SetMwmInfo */
486
487 #ifdef WSM
488 \f
489 /*************************************<->*************************************
490  *
491  *  SetMwmSaveSessionInfo (wmWindow)
492  *
493  *
494  *  Description:
495  *  -----------
496  *  This function sets up the WM_SAVE_YOURSELF property on the wm window
497  *
498  *
499  *  Inputs:
500  *  ------
501  *  wmWindow = motifWmInfo.wmWindow
502  *
503  * 
504  *  Outputs:
505  *  -------
506  *  WM_SAVE_YOURSELF = this property is set on the wm window
507  *
508  *************************************<->***********************************/
509
510 void SetMwmSaveSessionInfo (Window wmWindow)
511 {
512
513     Atom  property;
514     property = wmGD.xa_WM_SAVE_YOURSELF;
515     
516     XChangeProperty (DISPLAY, wmWindow, 
517                      wmGD.xa_WM_PROTOCOLS, XA_ATOM,
518                      32, PropModeReplace,
519                      (unsigned char *) &property, 1);
520     SetWMState(wmWindow, NORMAL_STATE, 0);
521     
522 } /* END OF FUNCTION SetMwmSaveSessionInfo */
523 #endif /* WSM */
524
525 \f
526 /*************************************<->*************************************
527  *
528  *  GetWMState (window)
529  *
530  *
531  *  Description:
532  *  -----------
533  *  This function gets the WM_STATE property on a client top-level
534  *  window.
535  *
536  *
537  *  Inputs:
538  *  ------
539  *  window = client window from which the WM_STATE property is to be retrieved
540  *
541  * 
542  *  Outputs:
543  *  -------
544  *  RETURN = a pointer to the WM_STATE property value (NULL if not defined)
545  *
546  *
547  *  Comments:
548  *  --------
549  *  This function will eventually be superceded when WM_STATE support is
550  *  added to the official X release.
551  * 
552  *************************************<->***********************************/
553
554 PropWMState *
555 GetWMState(
556         Window window )
557 {
558     int ret_val;
559     PropWMState *property = NULL;
560     Atom actual_type;
561     int actual_format;
562     unsigned long nitems;
563     unsigned long leftover;
564
565
566     ret_val = XGetWindowProperty (DISPLAY, window, wmGD.xa_WM_STATE, 
567                   0L, PROP_WM_STATE_ELEMENTS,
568                   False, wmGD.xa_WM_STATE, 
569                   &actual_type, &actual_format, 
570                   &nitems, &leftover, (unsigned char **)&property);
571
572     if (!((ret_val == Success) && (actual_type == wmGD.xa_WM_STATE) &&
573          (nitems == PROP_WM_STATE_ELEMENTS)))
574     {
575         /*
576          * The property could not be retrieved or is not correctly set up.
577          */
578
579         if (property)
580         {
581             XFree ((char *)property);
582             property = NULL;
583         }
584     }
585
586     return (property);
587
588 } /* END OF FUNCTION GetWMState */
589
590
591 \f
592 /*************************************<->*************************************
593  *
594  *  SetWMState (window, state, icon)
595  *
596  *
597  *  Description:
598  *  -----------
599  *  This function sets up the WM_STATE property on a client top-level
600  *  window.
601  *
602  *
603  *  Inputs:
604  *  ------
605  *  window = client window on which the WM_STATE property is to be set
606  *
607  *  state = state of the client application
608  *
609  *  icon = window manager's icon window
610  *
611  * 
612  *  Outputs:
613  *  -------
614  *  WM_STATE = this property is set on the client window
615  *
616  *
617  *  Comments:
618  *  --------
619  *  This function will eventually be superceded when WM_STATE support is
620  *  added to the official X release.
621  * 
622  *************************************<->***********************************/
623
624 void SetWMState (Window window, int state, Window icon)
625 {
626     PropWMState property;
627
628
629     property.state = state;
630     property.icon = icon;
631
632     XChangeProperty (DISPLAY, window, wmGD.xa_WM_STATE, wmGD.xa_WM_STATE, 32,
633         PropModeReplace, (unsigned char *)&property, PROP_WM_STATE_ELEMENTS);
634
635 } /* END OF FUNCTION SetWMState */
636
637
638 \f
639 /*************************************<->*************************************
640  *
641  *  PropMwmHints *
642  *  GetMwmHints (pCD)
643  *
644  *
645  *  Description:
646  *  -----------
647  *  This function reads any _MWM_HINTS property that is associated with a 
648  *  client window.
649  *
650  *  Inputs:
651  *  ------
652  *  pCD = pointer to client data
653  * 
654  *  Outputs:
655  *  -------
656  *  RETURN = ptr to mwm hints property, or NULL ptr if failure
657  *
658  *************************************<->***********************************/
659
660 PropMwmHints *
661 GetMwmHints(
662         ClientData *pCD )
663
664 {
665     int ret_val;
666     PropMwmHints *property = NULL;
667     Atom actual_type;
668     int actual_format;
669     unsigned long nitems;
670     unsigned long leftover;
671
672
673 #ifdef WSM
674     if (!HasProperty(pCD, wmGD.xa_MWM_HINTS))
675         ret_val = ~Success;
676     else
677 #endif /* WSM */
678     ret_val = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_MWM_HINTS, 
679                   0L, PROP_MWM_HINTS_ELEMENTS,
680                   False, wmGD.xa_MWM_HINTS, 
681                   &actual_type, &actual_format, 
682                   &nitems, &leftover, (unsigned char **)&property);
683
684     /*
685      * Retrieve the property data.
686      *
687      *     Motif 1.1.n clients: nitems  = PROP_MWM_HINTS_ELEMENTS
688      *     Motif 1.2 clients:   nitems  = PROP_MWM_HINTS_ELEMENTS + 2
689      *
690      * NOTES:  We don't need to check (nitems == PROP_MWM_HINTS_ELEMENTS)
691      *         since...
692      *
693      * If running Motif 1.1.n client with Mwm 1.2, then ignore extra elements
694      *    since property.flags won't have extra elements set.
695      *
696      * If running Motif 1.2 client with Mwm 1.1.n, then ignore extra elements
697      *    since Mwm 1.1.n won't try to access the extra elements.
698      */
699
700     if ((ret_val == Success) && (actual_type == wmGD.xa_MWM_HINTS))
701     {
702         return (property);                      /* indicate success */
703     }
704
705
706     /*
707      * The property could not be retrieved or is not correctly set up.
708      */
709
710     if (property)
711     {
712         XFree ((char *)property);
713     }
714
715     return (NULL);                      /* indicate failure */
716
717
718 } /* END OF FUNCTION GetMwmHints */
719
720
721 \f
722 /*************************************<->*************************************
723  *
724  *  PropMwmInfo *
725  *  GetMwmInfo (rootWindowOfScreen)
726  *
727  *
728  *  Description:
729  *  -----------
730  *  This function reads the _MOTIF_WM_INFO property from the root window if
731  *  it is setup.
732  * 
733  *  Inputs:
734  *  ------
735  *  pSD = pointer to screen data 
736  *
737  *  Outputs:
738  *  -------
739  *  RETURN = ptr to motif wm info property, or NULL ptr if no property
740  *
741  *************************************<->***********************************/
742
743 PropMwmInfo *GetMwmInfo (Window rootWindowOfScreen)
744 {
745     int ret_val;
746     PropMwmInfo *property = NULL;
747     Atom actual_type;
748     int actual_format;
749     unsigned long nitems;
750     unsigned long leftover;
751
752
753     ret_val = XGetWindowProperty (DISPLAY, rootWindowOfScreen,
754                                      wmGD.xa_MWM_INFO,
755                                      0L, PROP_MWM_INFO_ELEMENTS,
756                                      False, wmGD.xa_MWM_INFO,
757                                      &actual_type, &actual_format,
758                                      &nitems, &leftover,
759                                      (unsigned char **)&property);
760
761     if ((ret_val == Success) && (actual_type == wmGD.xa_MWM_INFO) &&
762         (nitems == PROP_MWM_INFO_ELEMENTS)) 
763     {
764         return (property);                      /* indicate success */
765     }
766
767
768     /*
769      * The property could not be retrieved or is not correctly set up.
770      */
771
772     if (property)
773     {
774         XFree ((char *)property);
775     }
776
777     return (NULL);                      /* indicate failure */
778
779
780 } /* END OF FUNCTION GetMwmInfo */
781
782
783 \f
784 /*************************************<->*************************************
785  *
786  *  ProcessWmColormapWindows (pCD)
787  *
788  *
789  *  Description:
790  *  -----------
791  *  This function retrieves and processes the WM_COLORMAP_WINDOWS client
792  *  window property.
793  *
794  *
795  *  Inputs:
796  *  ------
797  *  pCD = pointer to client data
798  *
799  * 
800  *  Outputs:
801  *  -------
802  *  pCD = (cmapWindows, clientCmapList, clientCmapCount, clientCmapIndex)
803  *
804  *************************************<->***********************************/
805
806 void ProcessWmColormapWindows (ClientData *pCD)
807 {
808     int rValue;
809     Window *property = NULL;
810     Atom actualType;
811     int actualFormat;
812     unsigned long leftover;
813     unsigned long nitems;
814     int i;
815     Window *pWindows;
816     Colormap *pColormaps;
817     int colormapCount;
818     XWindowAttributes wAttributes;
819     ClientData *pcd;
820     XSetWindowAttributes sAttributes;
821 #ifndef OLD_COLORMAP /* colormaps */
822     int *pCmapFlags;
823 #endif
824
825
826     /*
827      * pCD->clientCmapCount and pCD->clientCmapIndex are initialized in
828      * WmWinInfo.c.
829      */
830
831     /*
832      * Read the WM_COLORMAP_WINDOWS property.
833      */
834
835     rValue = XGetWindowProperty (DISPLAY, pCD->client,
836                  wmGD.xa_WM_COLORMAP_WINDOWS, 0L,
837                  (long)MAX_COLORMAP_WINDOWS_COUNT, False, AnyPropertyType,
838                  &actualType, &actualFormat, &nitems, &leftover,
839                  (unsigned char **)&property);
840
841
842     if ((rValue == Success) && (actualType != None) && (actualFormat == 32) &&
843         (nitems > 0))
844     {
845         /*
846          * WM_COLORMAP_WINDOWS exists and is a valid type.
847          */
848
849         if (!(pWindows = (Window *)XtMalloc ((nitems * sizeof (Window)) + 1)) ||
850             !(pColormaps = (Colormap *)XtMalloc ((nitems*sizeof(Colormap)) + 1)))
851         {
852             /* unable to allocate space */
853             Warning (((char *)GETMESSAGE(54, 3, "Insufficient memory for window management data")));
854             if (pWindows)
855             {
856                 XtFree ((char *)pWindows);
857             }
858         }
859 #ifndef OLD_COLORMAP /* colormap */
860         /* Is the above OSF code a bug -- allocates one extra byte, rather */
861         /* than one extra element, for the top window if needed? */
862         else if ( ! (pCmapFlags = (int *)XtCalloc(nitems+1,sizeof(int)))) {
863                         /* unable to allocate space */
864                         Warning (((char *)GETMESSAGE(54, 4, "Insufficient memory for window manager flags")));
865                         XtFree ((char *)pWindows); XtFree ((char *)pColormaps);
866         }
867 #endif
868         else
869         {
870             /*
871              * Check to see if the top-level client window is in the list.
872              * If it is not then add it to the head of the list.
873              */
874
875             for (i = 0; i < nitems; i++)
876             {
877                 if (property[i] == pCD->client)
878                 {
879                     break;
880                 }
881             }
882
883             colormapCount = 0;
884             if (i == nitems)
885             {
886                 /* add the client window to the colormap window list */
887                 pWindows[0] = pCD->client;
888                 pColormaps[0] = FindColormap (pCD, pCD->client);
889                 colormapCount++;
890             }
891
892             sAttributes.event_mask = (ColormapChangeMask);
893             for (i = 0; i < nitems; i++)
894             {
895                 if ((pColormaps[colormapCount] = 
896                      FindColormap (pCD, property[i])) != None)
897                 {
898                     pWindows[colormapCount] = property[i];
899                     colormapCount++;
900                 }
901                 else if (XFindContext (DISPLAY, property[i],
902                              wmGD.windowContextType, (caddr_t *)&pcd))
903                 {
904                     /*
905                      * The window is not a top level window or a window that
906                      * is already being tracked for colormap changes.
907                      * Track colormap attribute changes.
908                      */
909
910                     XChangeWindowAttributes (DISPLAY, property[i], CWEventMask,
911                         &sAttributes);
912                 
913
914                     if (XGetWindowAttributes (DISPLAY, property[i],
915                             &wAttributes))
916                     {
917                         pWindows[colormapCount] = property[i];
918                         pColormaps[colormapCount] = wAttributes.colormap;
919                         colormapCount++;
920                     }
921                 }
922             }
923
924             /*
925              * Free up the old colormap window data if it has been set.  Set
926              * new window contexts.
927              */
928
929             ResetColormapData (pCD, pWindows, colormapCount);
930                 
931
932             /*
933              * Set the colormap window data.
934              */
935
936             pCD->clientColormap = pColormaps[0];
937             if (colormapCount > 1)
938             {
939                 /*
940                  * The top level window and at least one other window is in
941                  * the colormap windows list.
942                  */
943
944                 pCD->clientCmapCount = colormapCount;
945                 pCD->cmapWindows = pWindows;
946                 pCD->clientCmapList = pColormaps;
947                 pCD->clientCmapIndex = 0;
948 #ifndef OLD_COLORMAP /* colormap */
949                 pCD->clientCmapFlags = pCmapFlags;
950 #endif
951             }
952             else
953             {
954                 /*
955                  * Only the top level window is being tracked for colormap
956                  * data.
957                  */
958
959                 pCD->clientCmapCount = 0;
960                 XtFree ((char *)pWindows);
961                 XtFree ((char *)pColormaps);
962 #ifndef OLD_COLORMAP /* colormap */
963                 XtFree((char *)pCmapFlags);
964 #endif
965             }
966         }
967     }
968
969
970     if (property)
971     {
972         XFree ((char *)property);
973     }
974
975
976 } /* END OF FUNCTION ProcessWmColormapWindows */
977
978
979 \f
980 /*************************************<->*************************************
981  *
982  *  FindColormap (pCD, window)
983  *
984  *
985  *  Description:
986  *  -----------
987  *  This function checks colormap information that is currently saved in
988  *  the client data for the colormap of the specified window.
989  *
990  *
991  *  Inputs:
992  *  ------
993  *  pCD = pointer to client data
994  *
995  *  window = get the colormap id for this window
996  *
997  * 
998  *  Outputs:
999  *  -------
1000  *  RETURN = colormap id for window (NULL if no colormap information)
1001  *
1002  *************************************<->***********************************/
1003
1004 Colormap FindColormap (ClientData *pCD, Window window)
1005 {
1006     Colormap colormap = (Colormap)0;
1007     int i;
1008
1009
1010     if (pCD->clientCmapCount == 0)
1011     {
1012         /*
1013          * If the colormap count is 0 there is no list of colormaps and
1014          * clientColormap is the colormap of the top-level window.
1015          */
1016
1017         if (window == pCD->client)
1018         {
1019             colormap = pCD->clientColormap;
1020         }
1021     }
1022     else
1023     {
1024         for (i = 0; i < pCD->clientCmapCount; i++)
1025         {
1026             if (pCD->cmapWindows[i] == window)
1027             {
1028                 colormap = pCD->clientCmapList[i];
1029                 break;
1030             }
1031         }
1032     }
1033
1034     return (colormap);
1035
1036 } /* END OF FUNCTION FindColormap */
1037
1038
1039 \f
1040 /*************************************<->*************************************
1041  *
1042  *  GetMwmMenuItems (pCD)
1043  *
1044  *
1045  *  Description:
1046  *  -----------
1047  *  This function reads and processes any _MWM_MENU property that is
1048  *  associated with a client window and returns a list of MenuItem structures
1049  *  specified by the property, or NULL.
1050  *
1051  *
1052  *  Inputs:
1053  *  ------
1054  *  pCD = pointer to client data
1055  *
1056  * 
1057  *  Outputs:
1058  *  -------
1059  *  Return = MenuItem list or NULL.
1060  *
1061  *************************************<->***********************************/
1062
1063 MenuItem *
1064 GetMwmMenuItems(
1065         ClientData *pCD )
1066 {
1067     int rValue;
1068     XTextProperty textProperty;
1069     MenuItem *menuItems;
1070
1071     /*
1072      * Read the _MWM_MENU property.
1073      */
1074
1075     textProperty.value = (unsigned char *)NULL;
1076     rValue = XGetTextProperty(DISPLAY, pCD->client, &textProperty,
1077                               wmGD.xa_MWM_MENU);
1078     if ((rValue == 0) || (textProperty.value == (unsigned char *)NULL))
1079     /* _MWM_MENU does not exist or it is an invalid type.  */
1080     {
1081         menuItems = NULL;
1082     }
1083
1084     else
1085     /* parse the property string */
1086     {
1087         char **textList;
1088         int nItems;
1089
1090         if (XmbTextPropertyToTextList(DISPLAY, &textProperty,
1091                                       &textList, &nItems) != Success)
1092         {
1093             menuItems = NULL;
1094         }
1095         else
1096         {
1097             menuItems = ParseMwmMenuStr (PSD_FOR_CLIENT(pCD), 
1098                                          (unsigned char *)textList[0]);
1099             XFreeStringList(textList);
1100         }
1101
1102         XFree((void *)textProperty.value);
1103     }
1104
1105     return (menuItems);
1106
1107 } /* END OF FUNCTION GetMwmMenuItems */
1108
1109 #ifdef WSM
1110
1111 \f
1112 /*************************************<->*************************************
1113  *
1114  *  GetWorkspaceHints (display, window, ppWsAtoms, pCount, pbAll)
1115  *
1116  *
1117  *  Description:
1118  *  -----------
1119  *  Get the contents of the WM_COMMAND property on a window
1120  *
1121  *
1122  *  Inputs:
1123  *  ------
1124  *  display     - X display 
1125  *  window      - window to get hints from
1126  *  ppWsAtoms   - pointer to a list of workspace atoms (to be returned)
1127  *  pCount      - ptr to a number of atoms (to be returned)
1128  *  pbAll       - ptr to a boolean (to be returned)
1129  *
1130  *
1131  *  Returns:
1132  *  --------
1133  *  Success if suceeded, otherwise failure code.
1134  * 
1135  *
1136  *  Outputs:
1137  *  -------
1138  *  *ppWsAtoms  - list of workspace atoms
1139  *  *pCount     - number of atoms in *ppWsAtoms
1140  *  *pbAll      - True if should put in all workspaces
1141  *
1142  *
1143  *  Comments:
1144  *  --------
1145  *  The caller must XtFree *ppWsAtoms when done!!!
1146  * 
1147  *************************************<->***********************************/
1148
1149 Status GetWorkspaceHints (Display *display, Window window, 
1150                           Atom **ppWsAtoms, unsigned int *pCount,
1151                           Boolean *pbAll)
1152 {
1153     int rcode;
1154     DtWorkspaceHints *pWsHints;
1155     Atom *paWs;
1156
1157     rcode = _DtWsmGetWorkspaceHints(display, window, &pWsHints);
1158     if (rcode == Success)
1159     {
1160         if (pWsHints->flags & DT_WORKSPACE_HINTS_WORKSPACES)
1161         {
1162             paWs = (Atom *) 
1163                 XtMalloc (pWsHints->numWorkspaces * sizeof(Atom));
1164             memcpy (paWs, 
1165                     pWsHints->pWorkspaces, 
1166                     (pWsHints->numWorkspaces * sizeof(Atom)));
1167
1168             *pCount = pWsHints->numWorkspaces;
1169             *ppWsAtoms = paWs;
1170         }
1171         else
1172         {
1173             *pCount = 0;
1174             *ppWsAtoms = NULL;
1175         }
1176
1177         if ((pWsHints->flags & DT_WORKSPACE_HINTS_WSFLAGS) &&
1178             (pWsHints->wsflags & DT_WORKSPACE_FLAGS_OCCUPY_ALL))
1179         {
1180             *pbAll = True;
1181         }
1182         else
1183         {
1184             *pbAll = False;
1185         }
1186
1187
1188         _DtWsmFreeWorkspaceHints (pWsHints);
1189     }
1190         
1191     return(rcode);
1192
1193 } /* END OF FUNCTION GetWorkspaceHints */
1194
1195 \f
1196 /*************************************<->*************************************
1197  *
1198  *  SetEmbeddedClientsProperty (propWindow, pEmbeddedClients, 
1199  *                              cEmbeddedCLients)
1200  *
1201  *
1202  *  Description:
1203  *  -----------
1204  *  This function writes the _DT_WORKSPACE_EMBEDDED_CLIENTS property
1205  *
1206  *
1207  *  Inputs:
1208  *  ------
1209  *  propWindow = window on which the property is to be written
1210  *  pEmbeddedClients = pointer to data (array of window IDs)
1211  *  cEmbeddedClients = number of window IDs in the array
1212  *
1213  *************************************<->***********************************/
1214
1215 void SetEmbeddedClientsProperty (Window propWindow, 
1216     Window *pEmbeddedClients, unsigned long cEmbeddedClients)
1217 {
1218     XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_EMBEDDED_CLIENTS, 
1219         wmGD.xa_DT_EMBEDDED_CLIENTS,
1220         32, PropModeReplace, (unsigned char *)pEmbeddedClients,
1221         cEmbeddedClients);
1222
1223 } /* END OF FUNCTION SetEmbeddedClientsProperty */
1224
1225 #ifdef HP_VUE
1226 \f
1227 /*************************************<->*************************************
1228  *
1229  *  SetWorkspaceInfo (propWindow, pWsInfo, cInfo)
1230  *
1231  *
1232  *  Description:
1233  *  -----------
1234  *  This function sets up the _DT_WORKSPACE_INFO property
1235  *
1236  *
1237  *  Inputs:
1238  *  ------
1239  *  propWindow = window on which the _DT_WORKSPACE_INFO property is to be set
1240  *  pWsInfo =  pointer to workspace info data
1241  *  cInfo = size of workspace info data
1242  * 
1243  *
1244  *************************************<->***********************************/
1245
1246 void SetWorkspaceInfo (Window propWindow, WorkspaceInfo *pWsInfo, unsigned long cInfo)
1247 {
1248     XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_WORKSPACE_INFO, 
1249         wmGD.xa_DT_WORKSPACE_INFO,
1250         32, PropModeReplace, (unsigned char *)pWsInfo,
1251         (cInfo * sizeof(WorkspaceInfo))/sizeof(long));
1252
1253 } /* END OF FUNCTION SetWorkspaceInfo */
1254 #endif /* HP_VUE */
1255
1256 \f
1257 /*************************************<->*************************************
1258  *
1259  *  SetWorkspaceListProperty (pSD)
1260  *
1261  *
1262  *  Description:
1263  *  -----------
1264  *  This function sets up the _DT_WORKSPACE_LIST property
1265  *
1266  *
1267  *  Inputs:
1268  *  ------
1269  *  pSD = ptr to screen data
1270  * 
1271  *
1272  *************************************<->***********************************/
1273
1274 void
1275 SetWorkspaceListProperty (WmScreenData *pSD)
1276 {
1277     WmWorkspaceData *pws;
1278     Atom *pWsList;
1279     int count;
1280
1281     pWsList = (Atom *) 
1282         XtMalloc (pSD->numWorkspaces * sizeof(Atom));
1283
1284     pws = pSD->pWS;
1285     for (count = 0; count < pSD->numWorkspaces; count++)
1286     {
1287         pWsList[count] = pws->id;
1288         pws++;
1289     }
1290
1291     XChangeProperty (DISPLAY, pSD->wmWorkspaceWin, 
1292         wmGD.xa_DT_WORKSPACE_LIST, 
1293         XA_ATOM,
1294         32, PropModeReplace, (unsigned char *)pWsList,
1295         (pSD->numWorkspaces * sizeof(Atom))/sizeof(long));
1296
1297     XtFree ((char *) pWsList);
1298
1299 } /* END OF FUNCTION SetWorkspaceListProperty */
1300
1301 \f
1302 /*************************************<->*************************************
1303  *
1304  *  SetCurrentWorkspaceProperty (pSD)
1305  *
1306  *
1307  *  Description:
1308  *  -----------
1309  *  This function sets up the _DT_WORKSPACE_CURRENT property
1310  *
1311  *
1312  *  Inputs:
1313  *  ------
1314  *  pSD = ptr to screen data
1315  * 
1316  *
1317  *************************************<->***********************************/
1318
1319 void
1320 SetCurrentWorkspaceProperty (WmScreenData *pSD)
1321 {
1322     Atom aCurrent;
1323
1324     aCurrent = pSD->pActiveWS->id;
1325
1326     XChangeProperty (DISPLAY, pSD->wmWorkspaceWin, 
1327         wmGD.xa_DT_WORKSPACE_CURRENT, 
1328         XA_ATOM,
1329         32, PropModeReplace, (unsigned char *)&aCurrent,
1330         (sizeof(Atom))/sizeof(long));
1331
1332     XSync (DISPLAY, False);     /* XFlush didn't work here, why? */
1333
1334 } /* END OF FUNCTION SetCurrentWorkspaceProperty */
1335
1336 \f
1337 /*************************************<->*************************************
1338  *
1339  *  SetWorkspaceInfoProperty (pWS)
1340  *
1341  *
1342  *  Description:
1343  *  -----------
1344  *  This function sets up the _DT_WORKSPACE_INFO_<name> property
1345  *  for a particular workspace
1346  *
1347  *
1348  *  Inputs:
1349  *  ------
1350  *  pWS = ptr to workspace data
1351  * 
1352  *
1353  *************************************<->***********************************/
1354
1355 void
1356 SetWorkspaceInfoProperty (WmWorkspaceData *pWS)
1357 {
1358     char *pch;
1359     Atom aProperty;
1360     String sTitle;
1361     char **ppchList;
1362     int iNumStrings;
1363     int count, iwin;
1364     int i, ix;
1365     Status status;
1366     XTextProperty tp;
1367 #define WIP_NUMBER_SIZE         16
1368
1369     /*
1370      * Construct our property name
1371      */
1372     pch = WorkspacePropertyName (pWS);
1373
1374     aProperty = XmInternAtom (DISPLAY, pch, FALSE);
1375
1376     XtFree ((char *) pch);
1377
1378     /*
1379      * Determine the number of strings in our vector. One for each of
1380      *
1381      *     workspace title
1382      *     pixel set id
1383      *     backdrop background
1384      *     backdrop foreground
1385      *     backdrop name
1386      *     number of backdrop windows
1387      *     list of backdrop windows
1388      */
1389     iNumStrings =  6;   /* number of fields minus backdrop window(s) */
1390     count = 1;          /* number of backdrop windows */
1391     iNumStrings += count;
1392
1393     /* allocate string vector */
1394     ppchList = (char **) XtMalloc (iNumStrings * sizeof (char *));
1395     pch = (char *) XtMalloc (iNumStrings * WIP_NUMBER_SIZE * sizeof(char));
1396     
1397     i = 0;
1398
1399     /* Convert workspace title to ascii */
1400     sTitle = (String) WmXmStringToString (pWS->title);
1401     ppchList[i++] = (char *) sTitle;
1402
1403     /*  Pixel set id */
1404     ix = (i * WIP_NUMBER_SIZE);
1405     sprintf (&pch[ix], "%d", pWS->backdrop.colorSet);
1406     ppchList[i++] = &pch[ix];
1407
1408     /* backdrop background */
1409     ix = (i * WIP_NUMBER_SIZE);
1410     sprintf (&pch[ix], "0x%lx", pWS->backdrop.background);
1411     ppchList[i++] = &pch[ix];
1412
1413     /* backdrop foreground */
1414     ix = (i * WIP_NUMBER_SIZE);
1415     sprintf (&pch[ix], "0x%lx", pWS->backdrop.foreground);
1416     ppchList[i++] = &pch[ix];
1417
1418     /* backdrop name */
1419     ix = (i * WIP_NUMBER_SIZE);
1420     sprintf (&pch[ix], "0x%lx", pWS->backdrop.nameAtom);
1421     ppchList[i++] = &pch[ix];
1422
1423     /* number of backdrop windows */
1424     ix = (i * WIP_NUMBER_SIZE);
1425     if ((pWS->backdrop.window == None))
1426     {
1427         strcpy (&pch[ix], "0");
1428     }
1429     else
1430     {
1431         sprintf (&pch[ix], "%d", count);
1432     }
1433     ppchList[i++] = &pch[ix];
1434
1435     /* backdrop windows */
1436     /* 
1437      * One or zero backdrop windows 
1438      * (NULL written if zero)
1439      */
1440     ix = (i * WIP_NUMBER_SIZE);
1441     sprintf (&pch[ix], "0x%lx", pWS->backdrop.window);
1442     ppchList[i++] = &pch[ix];
1443
1444     /*
1445      * Write out the property
1446      */
1447     status = XmbTextListToTextProperty (DISPLAY, ppchList, iNumStrings,
1448                                             XStdICCTextStyle, &tp);
1449     if ((status == Success) || (status > 0))
1450     {
1451         /*
1452          * Complete or partial conversion
1453          */
1454         XSetTextProperty (DISPLAY, pWS->pSD->wmWorkspaceWin, &tp, aProperty);
1455         XFree (tp.value);
1456     }
1457
1458     XtFree ((char *) ppchList);
1459     XtFree (pch);
1460     if (sTitle) XtFree ((char *)sTitle);
1461
1462 } /* END OF FUNCTION SetWorkspaceInfoProperty */
1463
1464 \f
1465 /*************************************<->*************************************
1466  *
1467  *  DeleteWorkspaceInfoProperty (pWS)
1468  *
1469  *
1470  *  Description:
1471  *  -----------
1472  *  This function deletes a _DT_WORKSPACE_INFO_<name> property
1473  *  for a particular workspace
1474  *
1475  *
1476  *  Inputs:
1477  *  ------
1478  *  pWS = ptr to workspace data
1479  * 
1480  *
1481  *************************************<->***********************************/
1482
1483 void
1484 DeleteWorkspaceInfoProperty (WmWorkspaceData *pWS)
1485 {
1486     char *pch;
1487     Atom aProperty;
1488
1489     /*
1490      * Get the atom for the workspace property.
1491      */
1492     pch = WorkspacePropertyName (pWS);
1493
1494     aProperty = XmInternAtom (DISPLAY, pch, FALSE);
1495
1496     XtFree ((char *) pch);
1497
1498     /*
1499      * Do the property deletion
1500      */
1501     XDeleteProperty (DISPLAY, pWS->pSD->wmWorkspaceWin, aProperty);
1502     XFlush (DISPLAY);
1503
1504
1505 } /* END OF FUNCTION DeleteWorkspaceInfoProperty */
1506
1507 \f
1508 /*************************************<->*************************************
1509  *
1510  *  WorkspacePropertyName (pWS)
1511  *
1512  *
1513  *  Description:
1514  *  -----------
1515  *  This function returns a string containing the property name for a 
1516  *  workspace.
1517  *
1518  *
1519  *  Inputs:
1520  *  ------
1521  *  pWS = ptr to workspace data
1522  *
1523  *  Returns
1524  *  -------
1525  *  string containing the workspace property name (Free with XtFree)
1526  *
1527  *
1528  *************************************<->***********************************/
1529
1530 char *
1531 WorkspacePropertyName (WmWorkspaceData *pWS)
1532 {
1533     char *pch;
1534     char *pchName;
1535     int len;
1536     Atom aProperty;
1537
1538     /*
1539      * Construct our property name
1540      */
1541     pchName = pWS->name;
1542     len = strlen(pchName) + strlen (_XA_DT_WORKSPACE_INFO) + 4;
1543
1544     pch = (char *) XtMalloc (len);
1545     strcpy (pch, _XA_DT_WORKSPACE_INFO);
1546     strcat (pch, "_");
1547     strcat (pch, pchName);
1548
1549     return (pch);
1550
1551 } /* END OF FUNCTION WorkspacePropertyName */
1552
1553 \f
1554 /*************************************<->*************************************
1555  *
1556  *  SetWorkspacePresence (propWindow, pWsPresence, cPresence)
1557  *
1558  *
1559  *  Description:
1560  *  -----------
1561  *  This function sets up the _DT_WORKSPACE_PRESENCE property
1562  *
1563  *
1564  *  Inputs:
1565  *  ------
1566  *  propWindow = window on which the _DT_WORKSPACE_PRESENCE property 
1567  *               is to be set
1568  *  pWsPresence =  pointer to workspace presence data
1569  *  cPresence = size of workspace presence data
1570  * 
1571  *
1572  *************************************<->***********************************/
1573
1574 void SetWorkspacePresence (Window propWindow, Atom *pWsPresence, unsigned long cPresence)
1575 {
1576     XChangeProperty (DISPLAY, propWindow, wmGD.xa_DT_WORKSPACE_PRESENCE, 
1577         wmGD.xa_DT_WORKSPACE_PRESENCE, 32, PropModeReplace, 
1578         (unsigned char *)pWsPresence, cPresence);
1579     XFlush (DISPLAY);
1580
1581 } /* END OF FUNCTION SetWorkspacePresence */
1582
1583
1584
1585 \f
1586 /*************************************<->*************************************
1587  *
1588  *  GetDtSessionHints (pSD, sNum)
1589  *
1590  *
1591  *  Description:
1592  *  -----------
1593  *  This function reads and processes _DT_SESSION_HINTS property that is
1594  *  associated with the root window of each screen managed by dtwm
1595  *
1596  *
1597  *  Inputs:
1598  *  ------
1599  *
1600  *
1601  *  Outputs:
1602  *  -------
1603  *
1604  *************************************<->***********************************/
1605
1606 void GetDtSessionHints (WmScreenData *pSD, int sNum)
1607
1608 {
1609
1610     int           rValue;
1611     char          *property = NULL;
1612     Atom          actualType;
1613     int           actualFormat;
1614     unsigned long leftover;
1615     unsigned long nitems;
1616
1617     
1618
1619     /*
1620      * Read the  property.
1621      */
1622
1623     rValue = XGetWindowProperty (DISPLAY, pSD->rootWindow,
1624                                  wmGD.xa_DT_SESSION_HINTS, 0L,
1625                                  (long)1000000, False, AnyPropertyType,
1626                                  &actualType, &actualFormat, &nitems,
1627                                  &leftover, (unsigned char **)&property);
1628
1629
1630     if ((rValue != Success) || (actualType == None) || (actualFormat != 8))
1631         /* _DT_SESSION_HINTS does not exist or it is an invalid type.  */
1632     {
1633         pSD->pDtSessionItems = NULL;
1634
1635     }
1636
1637     else
1638         /* parse the property string */
1639     {
1640         ParseDtSessionHints (pSD, (unsigned char *)property);
1641     }
1642
1643
1644     if (property)
1645     {
1646         XFree ((char *)property);
1647     }
1648     
1649     /*
1650      * Delete the property so we don't see it if the user
1651      * restarts dtwm.
1652      */
1653 #ifndef DEBUG_SESSION_HINTS
1654     XDeleteProperty (DISPLAY, pSD->rootWindow, wmGD.xa_DT_SESSION_HINTS);
1655 #endif /* DEBUG_SESSION_HINTS */
1656 } /* END OF FUNCTION GetDtSessionHints */
1657
1658
1659
1660 \f
1661 /*************************************<->*************************************
1662  *
1663  *  GetDtWmRequest (pSD, pszReq, pmore)
1664  *
1665  *
1666  *  Description:
1667  *  -----------
1668  *  This function returns the next request
1669  *
1670  *
1671  *  Inputs:
1672  *  ------
1673  *  pSD - pointer to screen data
1674  *  psdReq - pointer to a char pointer
1675  *
1676  *
1677  *  Outputs:
1678  *  -------
1679  *  *pszReq     - pointer to null terminated string containing next
1680  *                request
1681  *  *pmore      - set to true if more data is left in the property
1682  *
1683  *  Comments:
1684  *  ---------
1685  *  The data for pszReq is allocated in here. The caller must free up
1686  *  this space using XtFree.
1687  *
1688  *
1689  *************************************<->***********************************/
1690
1691 void 
1692 GetDtWmRequest (
1693                 WmScreenData *pSD, 
1694                 char **pszReq, 
1695                 Boolean *pmore)
1696
1697 {
1698
1699     int           rValue;
1700     char         *chRequest = NULL;
1701     static char  *property = NULL;
1702     static int    iNext = -1;
1703     int           i;
1704     Atom          actualType;
1705     int           actualFormat;
1706     unsigned long leftover;
1707     static unsigned long nitems = 0;
1708
1709     
1710     /*
1711      * We need to read the property again if we have no data left
1712      * over from last time;
1713      */
1714     if (property == NULL)
1715     {
1716 #ifdef PARANOID
1717         /*
1718          * Lock down the server to prevent changes to this
1719          * property while we "edit" it.
1720          */
1721         XGrabServer(DISPLAY);
1722 #endif /* PARANOID */
1723
1724         /*
1725          * Read the property and delete it.
1726          */
1727         rValue = XGetWindowProperty (DISPLAY, pSD->wmWorkspaceWin,
1728                                      wmGD.xa_DT_WM_REQUEST, 0L,
1729                                      (long)1000000, True, AnyPropertyType,
1730                                      &actualType, &actualFormat, &nitems,
1731                                      &leftover, (unsigned char **)&property);
1732
1733 #ifdef PARANOID
1734         /* Give the server back */ 
1735         XUngrabServer(DISPLAY);
1736 #endif /* PARANOID */
1737
1738         /* 
1739          * Validate the property that we've read
1740          */
1741         if ((rValue != Success) || 
1742             (actualType == None) || 
1743             (actualFormat != 8))
1744         {
1745             /* The property does not exist or it is an invalid type. */
1746             property = NULL;
1747             iNext = -1;
1748             nitems = 0;
1749         }
1750         else
1751         {
1752             /* the property is fine, set the index of the next char. */
1753             iNext = 0;
1754         }
1755     }
1756
1757
1758     /* 
1759      * If we've got something, then extract and return the next
1760      * request.
1761      */
1762     if (property && iNext >= 0)
1763     {
1764         int len = 0;
1765
1766         for (i=iNext; i<nitems; i++)
1767         {
1768             if (property [i] == '\0')
1769             {
1770                 break;
1771             }
1772         }
1773         if (i>=nitems) i=nitems;
1774
1775         len = i - iNext + 1 + ((property[i] == '\0') ? 0 : 1);
1776
1777         chRequest = (char *) XtMalloc (len);
1778         if (chRequest == NULL)
1779         {
1780             Warning (((char *)GETMESSAGE(54, 2, "Insufficient memory for window management data")));
1781         }
1782         else
1783         {
1784             /* dequeue the request */
1785             strncpy (chRequest, &property[iNext], len);
1786             if (property[i] != '\0')
1787             {
1788                 chRequest[len-1]='\0';
1789             }
1790             iNext = i+1;
1791         }
1792         
1793         if (iNext >= nitems)
1794         {
1795             /*
1796              * Extracted the last request, free up the storage
1797              * and reset for next time.
1798              */
1799             XFree ((char *)property);
1800             iNext = -1;
1801             property = NULL;
1802         }
1803     }
1804     
1805     *pmore = (property != NULL);
1806     *pszReq = chRequest;
1807
1808 } /* END OF FUNCTION GetDtWmRequest */
1809
1810 \f
1811 /*************************************<->*************************************
1812  *
1813  *  GetIntialPropertyList (ClientData *)
1814  *
1815  *
1816  *  Description:
1817  *  -----------
1818  *  Get the list of initial properties on the window
1819  *
1820  *
1821  *  Inputs:
1822  *  ------
1823  *  pCD         - pointer to client data
1824  *
1825  * 
1826  *  Outputs:
1827  *  -------
1828  *  pCD         - paInitialProperties member is updated
1829  *
1830  *
1831  *  Comments:
1832  *  --------
1833  *  The caller must XFree the paIntialialProperties member!
1834  * 
1835  *************************************<->***********************************/
1836
1837 void
1838 GetInitialPropertyList (ClientData *pCD)
1839 {
1840     Atom *paList;
1841     int iProps;
1842
1843     paList = XListProperties (DISPLAY, pCD->client, &iProps);
1844
1845     if (paList)
1846     {
1847         pCD->paInitialProperties = paList;
1848         pCD->numInitialProperties = iProps;
1849     }
1850     else
1851     {
1852         pCD->paInitialProperties = NULL;
1853         pCD->numInitialProperties = 0;
1854     }
1855
1856 } /* END OF FUNCTION GetInitialPropertyList */
1857
1858 \f
1859 /*************************************<->*************************************
1860  *
1861  *  DiscardIntialPropertyList (ClientData *)
1862  *
1863  *
1864  *  Description:
1865  *  -----------
1866  *  Tosses out the intial property list for a client, frees data
1867  *
1868  *
1869  *  Inputs:
1870  *  ------
1871  *  pCD         - pointer to client data
1872  *
1873  * 
1874  *  Outputs:
1875  *  -------
1876  *  pCD         - paInitialProperties member is updated
1877  *
1878  *
1879  *  Comments:
1880  *  --------
1881  *  
1882  * 
1883  *************************************<->***********************************/
1884
1885 void
1886 DiscardInitialPropertyList (ClientData *pCD)
1887 {
1888     if (pCD->paInitialProperties)
1889     {
1890         /*
1891          * Free the initial property list. 
1892          * (see HasProperty() function)
1893          */
1894         XFree ((char *) pCD->paInitialProperties);
1895         pCD->paInitialProperties = NULL;
1896         pCD->numInitialProperties = 0;
1897     }
1898 } /* END OF FUNCTION DiscardInitialPropertyList */
1899
1900 \f
1901 /*************************************<->*************************************
1902  *
1903  *  HasProperty (pCD, aProperty)
1904  *
1905  *
1906  *  Description:
1907  *  -----------
1908  *  Returns True if this client had this property when it was mapped
1909  *
1910  *
1911  *  Inputs:
1912  *  ------
1913  *  pCD         - pointer to client data
1914  *  aProperty   - atom of property to test for
1915  *
1916  * 
1917  *  Outputs:
1918  *  -------
1919  *  Return      - True if this property was on the initial list for this
1920  *                client; False otherwise.
1921  *
1922  *
1923  *  Comments:
1924  *  --------
1925  * 
1926  *************************************<->***********************************/
1927
1928 Boolean
1929 HasProperty (
1930         ClientData *    pCD,
1931         Atom            aProperty)
1932 {
1933     Boolean     bFound = False;
1934     Atom  *     paList;
1935     int         count;
1936
1937     paList = pCD->paInitialProperties;
1938
1939     if (paList)
1940     {
1941         count = pCD->numInitialProperties;
1942         while ((!bFound) && (count > 0))
1943         {
1944             bFound = (*paList == aProperty);
1945             count--;
1946             paList++;
1947         }
1948     }
1949     else
1950     {
1951         /*
1952          * The property list doesn't exist. Return
1953          * True to force a read of this property. The most likely
1954          * case is that this property was updated after the 
1955          * window was managed and needs to be read.
1956          */
1957         bFound = True;
1958     }
1959     return (bFound);
1960
1961 } /* END OF FUNCTION HasProperty */
1962 #endif /* WSM */
1963
1964
1965