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