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