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