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