Spelling fixes
[oweals/cde.git] / cde / programs / dtwm / WmOL.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 #ifndef NO_OL_COMPAT
24 /* 
25  * (c) Copyright 1989 Sun Microsystems, Inc.
26  * (c) Copyright 1993 HEWLETT-PACKARD COMPANY 
27  * ALL RIGHTS RESERVED 
28  */ 
29 #ifdef REV_INFO
30 #ifndef lint
31 static char rcsid[] = "$XConsortium: WmOL.c /main/4 1995/11/01 11:45:08 rswiston $"
32 #endif
33 #endif
34
35 /*
36  * Included Files:
37  */
38 #include <stdlib.h>
39 #include "WmGlobal.h"
40 #include "WmOL.h"
41 #include "WmProperty.h"
42 #include <Xm/AtomMgr.h>
43
44 #define ValidPropertyList(pcd) ((pcd)->paInitialProperties != NULL)
45
46
47 \f
48 /*************************************<->*************************************
49  *
50  *  InitOLCompat ()
51  *
52  *  Description:
53  *  -----------
54  *  Interns the atoms necessary for OL protocols.
55  *
56  *  Inputs:
57  *  ------
58  *
59  *  Outputs:
60  *  --------
61  * 
62  *************************************<->***********************************/
63 void 
64 InitOLCompat(void)
65 {
66     wmGD.xa_OL_WIN_ATTR =
67             XmInternAtom (DISPLAY, OL_WIN_ATTR, False);
68     wmGD.xa_OL_DECOR_RESIZE =
69             XmInternAtom (DISPLAY, OL_DECOR_RESIZE, False);
70     wmGD.xa_OL_DECOR_HEADER =
71             XmInternAtom (DISPLAY, OL_DECOR_HEADER, False);
72     wmGD.xa_OL_DECOR_CLOSE =
73             XmInternAtom (DISPLAY, OL_DECOR_CLOSE, False);
74     wmGD.xa_OL_DECOR_PIN =
75             XmInternAtom (DISPLAY, OL_DECOR_PIN, False);
76     wmGD.xa_OL_DECOR_ADD =
77             XmInternAtom (DISPLAY, OL_DECOR_ADD, False);
78     wmGD.xa_OL_DECOR_DEL =
79             XmInternAtom (DISPLAY, OL_DECOR_DEL, False);
80     wmGD.xa_OL_WT_BASE =
81             XmInternAtom (DISPLAY, OL_WT_BASE, False);
82     wmGD.xa_OL_WT_COMMAND =
83             XmInternAtom (DISPLAY, OL_WT_CMD, False);
84     wmGD.xa_OL_WT_HELP =
85             XmInternAtom (DISPLAY, OL_WT_HELP, False);
86     wmGD.xa_OL_WT_NOTICE =
87             XmInternAtom (DISPLAY, OL_WT_NOTICE, False);
88     wmGD.xa_OL_WT_OTHER =
89             XmInternAtom (DISPLAY, OL_WT_OTHER, False);
90     wmGD.xa_OL_PIN_IN =
91             XmInternAtom (DISPLAY, OL_PIN_IN, False);
92     wmGD.xa_OL_PIN_OUT =
93             XmInternAtom (DISPLAY, OL_PIN_OUT, False);
94     wmGD.xa_OL_MENU_LIMITED =
95             XmInternAtom (DISPLAY, OL_MENU_LIMITED, False);
96     wmGD.xa_OL_MENU_FULL =
97             XmInternAtom (DISPLAY, OL_MENU_FULL, False);
98
99 } /* END OF FUNCTION InitOLCompat */
100
101
102 \f
103 /*************************************<->*************************************
104  *
105  *  HasOpenLookHints (pCD)
106  *
107  *  Description:
108  *  -----------
109  *  Returns True if this client has OpenLook hints on it.  
110  *
111  *  Inputs:
112  *  ------
113  *  pCD  =  pointer to client data
114  *
115  *  Outputs:
116  *  --------
117  *  Returns True if client has the _OL_WIN_ATTR property on it.
118  * 
119  *************************************<->***********************************/
120 Boolean 
121 HasOpenLookHints(
122         ClientData *pCD )
123 {
124     Boolean rval = False;
125     OLWinAttr *property = NULL;
126
127     if (ValidPropertyList (pCD) &&
128         HasProperty(pCD, wmGD.xa_OL_WIN_ATTR))
129     {
130         rval = True;
131     }
132     else if ((property=GetOLWinAttr (pCD)) != NULL)
133     {
134         XFree ((char *) property);
135         rval = True;
136     }
137
138     return (rval);
139
140 } /* END OF FUNCTION HasOpenLookHints */
141
142
143 \f
144 /*************************************<->*************************************
145  *
146  *  GetOLWinAttr (pCD)
147  *
148  *  Description:
149  *  -----------
150  *  Fetches the OLWinAttr property off of the client
151  *
152  *  Inputs:
153  *  ------
154  *  pCD  =  pointer to client data
155  *
156  *  Outputs:
157  *  --------
158  *  Returns a pointer to the OLWinAttr property if found and valid.
159  *  (Returned data should be freed with XFree())
160  *  Returns NULL pointer otherwise.
161  * 
162  *************************************<->***********************************/
163 OLWinAttr * 
164 GetOLWinAttr(
165         ClientData *pCD )
166 {
167     Boolean rval = False;
168     OLWinAttr *property = NULL;
169     OLWinAttr *prop_new;
170     Atom actual_type;
171     int actual_format;
172     unsigned long nitems;
173     unsigned long leftover;
174     int ret_val;
175
176     ret_val = XGetWindowProperty (DISPLAY, pCD->client, wmGD.xa_OL_WIN_ATTR, 
177                   0L, ENTIRE_CONTENTS,
178                   False, wmGD.xa_OL_WIN_ATTR, 
179                   &actual_type, &actual_format, 
180                   &nitems, &leftover, (unsigned char **)&property);
181
182     if (ret_val != Success)
183     {
184             property = NULL;
185     }
186     else if ((actual_format != 32) || 
187         (actual_type != wmGD.xa_OL_WIN_ATTR)) 
188     {
189             if (property) 
190                 XFree((char *)property);
191             property = NULL;
192     }
193
194     if (property && (nitems == OLDOLWINATTRLENGTH))
195     {
196         /* Old size, convert to new size */
197         /* 
198          * !!! Should use XAlloc() here, but Xlib doesn't
199          *     define an inverse function of XFree(). !!!
200          */
201         prop_new = (OLWinAttr *) malloc (sizeof(OLWinAttr));
202
203         prop_new->flags = WA_WINTYPE | WA_MENUTYPE | WA_PINSTATE;
204         prop_new->win_type = ((old_OLWinAttr *)property)->win_type;
205         prop_new->menu_type = ((old_OLWinAttr *)property)->menu_type;
206         prop_new->pin_initial_state = 
207                         ((old_OLWinAttr *)property)->pin_initial_state;
208
209         XFree ((char *) property);
210         property = prop_new;
211     }
212
213     /* convert pin state for old clients */
214     if (property && (property->flags & WA_PINSTATE))
215     {
216         if (property->pin_initial_state == wmGD.xa_OL_PIN_IN)
217         {
218             property->pin_initial_state = PIN_IN;
219         }
220         else if (property->pin_initial_state == wmGD.xa_OL_PIN_OUT)
221         {
222             property->pin_initial_state = PIN_OUT;
223         }
224     }
225
226     return (property);
227
228 } /* END OF FUNCTION GetOLWinAttr */
229
230 \f
231 /*************************************<->*************************************
232  *
233  *  GetOLDecorFlags (pCD, property, pDecor)
234  *
235  *  Description:
236  *  -----------
237  *  Fetches the _OL_DECOR_ADD or _OL_DECOR_DEL property off of the 
238  *  client and returns OL flavored decor flags.
239  *
240  *  Inputs:
241  *  ------
242  *  pCD  =  pointer to client data
243  *  property = property to fetch
244  *  pDecor = pointer to OL decor flags word
245  *
246  *  Outputs:
247  *  --------
248  *  Return =  True if property found, False otherwise
249  *  *pDecor = OL decor flags if valid property found, 
250  *            undefined if property not found.
251  * 
252  *************************************<->***********************************/
253 Boolean
254 GetOLDecorFlags(
255         ClientData *pCD,
256         Atom property,
257         unsigned long *pDecor)
258 {
259     int status, i;
260     Boolean rval;
261     Atom actual_type;
262     int actual_format;
263     unsigned long nitems;
264     unsigned long leftover;
265     Atom *pAtoms = NULL;
266
267     status = XGetWindowProperty (DISPLAY, pCD->client, property,
268                   0L, ENTIRE_CONTENTS,
269                   False, XA_ATOM, 
270                   &actual_type, &actual_format, 
271                   &nitems, &leftover, (unsigned char **)&pAtoms);
272
273     if ((status != Success) || 
274         !pAtoms || 
275         (nitems == 0) ||
276         (actual_type != XA_ATOM) ||
277         (actual_format != 32)) 
278     {
279             if (pAtoms)
280                     XFree((char *)pAtoms);
281             rval = False;
282     }
283     else
284     {
285         *pDecor = 0;
286
287         /*
288          * We only look for the ones we might be interested in.
289          * Several OL decoration types are ignored.
290          */
291         for (i = 0; i < nitems; i++) {
292                 if (pAtoms[i] == wmGD.xa_OL_DECOR_RESIZE)
293                         *pDecor |= OLDecorResizable;
294                 else if (pAtoms[i] == wmGD.xa_OL_DECOR_HEADER)
295                         *pDecor |= OLDecorHeader;
296                 else if (pAtoms[i] == wmGD.xa_OL_DECOR_CLOSE)
297                         *pDecor |= OLDecorCloseButton;
298                 else if (pAtoms[i] == wmGD.xa_OL_DECOR_PIN)
299                         *pDecor |= OLDecorPushPin;
300         }
301
302         XFree((char *)pAtoms);
303         rval = True;
304
305     }
306     return (rval);
307
308 } /* END OF FUNCTION GetOLDecorFlags */
309
310
311 \f
312 /*************************************<->*************************************
313  *
314  *  ProcessOLDecoration (pCD)
315  *
316  *  Description:
317  *  -----------
318  *
319  *  Inputs:
320  *  ------
321  *  pCD  =  pointer to client data
322  *
323  *  Outputs:
324  *  --------
325  *  pCD = possibly modified with new decoration info
326  * 
327  *************************************<->***********************************/
328 void
329 ProcessOLDecoration(
330         ClientData *pCD)
331 {
332     OLWinAttr * pOLWinAttr;
333     unsigned long OLdecor;
334     long decorMask;
335
336     if (HasOpenLookHints (pCD) && 
337         ((pOLWinAttr = GetOLWinAttr (pCD)) != NULL))
338     {
339         /*
340          * This window already has some decoration applied to
341          * it based on its ICCCM type (transient or not).
342          * Use the OL hints to construct a mask to further 
343          * modify these decorations.
344          */
345         if ((pOLWinAttr->flags & WA_WINTYPE) == 0) 
346         {
347             /*
348              * Window type not specified, assume all decorations
349              */
350             decorMask = WM_DECOR_ALL;
351         } 
352         else if (pOLWinAttr->win_type == wmGD.xa_OL_WT_BASE)
353         {
354             /* 
355              * Base windows can have all decorations
356              */
357             decorMask = WM_DECOR_ALL;
358         } 
359         else if (pOLWinAttr->win_type == wmGD.xa_OL_WT_COMMAND) 
360         {
361             /*
362              * Command windows have titles, pins (close button), and
363              * resize handles.
364              */
365             decorMask = WM_DECOR_TITLE | WM_DECOR_SYSTEM | WM_DECOR_RESIZEH;
366         }
367         else if (pOLWinAttr->win_type == wmGD.xa_OL_WT_HELP) 
368         {
369             /*
370              * Help windows have titles and pins (close button).
371              * No resize, but give it a border to look nicer.
372              */
373             decorMask = (WM_DECOR_TITLE | WM_DECOR_SYSTEM | WM_DECOR_BORDER);
374         }
375         else if ((pOLWinAttr->win_type == wmGD.xa_OL_WT_NOTICE)  &&
376                  (pOLWinAttr->win_type == wmGD.xa_OL_WT_OTHER))
377         {
378             decorMask = WM_DECOR_NONE;
379         } 
380         else
381         {
382             decorMask = WM_DECOR_ALL;
383         }
384
385         if (GetOLDecorAdd(pCD,&OLdecor))
386         {
387             if (OLdecor & OLDecorResizable)
388             {
389                 decorMask |= WM_DECOR_RESIZEH;
390             }
391             if (OLdecor & OLDecorHeader)
392             {
393                 decorMask |= WM_DECOR_TITLE;
394             }
395             if (OLdecor & OLDecorCloseButton)
396             {
397                 /* OL "close" is same as "Motif" minimize */
398                 decorMask |= MWM_DECOR_MINIMIZE;
399             }
400             if (OLdecor & OLDecorPushPin)
401             {
402                 /* 
403                  * windows with pins can't be minimized 
404                  */
405                 decorMask &= ~MWM_DECOR_MINIMIZE;
406                 decorMask |= MWM_DECOR_TITLE | MWM_DECOR_MENU;
407             }
408         }
409
410         if (GetOLDecorDel(pCD,&OLdecor))
411         {
412             if (OLdecor & OLDecorResizable)
413             {
414                 decorMask &= ~MWM_DECOR_RESIZEH;
415             }
416             if (OLdecor & OLDecorHeader)
417             {
418                 decorMask &= ~WM_DECOR_TITLEBAR;
419             }
420             if (OLdecor & OLDecorCloseButton)
421             {
422                 /* OL "close" is same as "Motif" minimize */
423                 decorMask &= ~MWM_DECOR_MINIMIZE;
424             }
425
426             /* push pin is ignored here */
427
428         }
429
430         /*
431          * If the window has a push pin or a limited menu,
432          * then consider it very similar to a secondary window.
433          */
434         if (((pOLWinAttr->flags & WA_PINSTATE) &&
435              (pOLWinAttr->pin_initial_state == PIN_IN)) ||
436             ((pOLWinAttr->flags & WA_MENUTYPE) &&
437              (pOLWinAttr->menu_type == wmGD.xa_OL_MENU_LIMITED)))
438         {
439             decorMask &= ~(MWM_DECOR_MINIMIZE | MWM_DECOR_MAXIMIZE);
440             pCD->bPseudoTransient = True;
441             pCD->dtwmFunctions &= ~DtWM_FUNCTION_OCCUPY_WS;
442         }
443
444         /* 
445          * Reduce decoration on this window according to OL hints
446          */
447         pCD->clientDecoration &= decorMask;
448
449         /*
450          * Reduce client functions if necessary.
451          */
452         if (!(decorMask & MWM_DECOR_MINIMIZE))
453         {
454             pCD->clientFunctions &= ~MWM_FUNC_MINIMIZE;
455         }
456         if (!(decorMask & MWM_DECOR_MAXIMIZE))
457         {
458             pCD->clientFunctions &= ~MWM_FUNC_MAXIMIZE;
459         }
460         if (!(decorMask & MWM_DECOR_RESIZEH))
461         {
462             pCD->clientFunctions &= ~MWM_FUNC_RESIZE;
463         }
464
465         /* 
466          * Set the clients secondariesOnTop value to false to allow
467          * open look transient behaviour (transients below primary).
468          */
469         pCD->secondariesOnTop = False;
470         
471         if (pOLWinAttr)
472             XFree((char *)pOLWinAttr);
473     }
474
475 } /* END OF FUNCTION ProcessOLDecoration */
476
477 #endif /* NO_OL_COMPAT */