1 /*
2  * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3  * Copyright (C) 2003-2014 Kim Woelders
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to
7  * deal in the Software without restriction, including without limitation the
8  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9  * sell copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies of the Software, its documentation and marketing & publicity
14  * materials, and acknowledgment shall be given in the documentation, materials
15  * and software packages that this Software was used.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 #include "config.h"
25 #include "ewins.h"
26 #include "hints.h"
27 #include "xprop.h"
28 
29 /* Motif window hints */
30 #define MWM_HINTS_FUNCTIONS           (1L << 0)
31 #define MWM_HINTS_DECORATIONS         (1L << 1)
32 #define MWM_HINTS_INPUT_MODE          (1L << 2)
33 #define MWM_HINTS_STATUS              (1L << 3)
34 
35 /* bit definitions for MwmHints.functions */
36 #define MWM_FUNC_ALL            (1L << 0)
37 #define MWM_FUNC_RESIZE         (1L << 1)
38 #define MWM_FUNC_MOVE           (1L << 2)
39 #define MWM_FUNC_MINIMIZE       (1L << 3)
40 #define MWM_FUNC_MAXIMIZE       (1L << 4)
41 #define MWM_FUNC_CLOSE          (1L << 5)
42 
43 /* bit definitions for MwmHints.decorations */
44 #define MWM_DECOR_ALL                 (1L << 0)
45 #define MWM_DECOR_BORDER              (1L << 1)
46 #define MWM_DECOR_RESIZEH             (1L << 2)
47 #define MWM_DECOR_TITLE               (1L << 3)
48 #define MWM_DECOR_MENU                (1L << 4)
49 #define MWM_DECOR_MINIMIZE            (1L << 5)
50 #define MWM_DECOR_MAXIMIZE            (1L << 6)
51 
52 /* bit definitions for MwmHints.inputMode */
53 #define MWM_INPUT_MODELESS                  0
54 #define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
55 #define MWM_INPUT_SYSTEM_MODAL              2
56 #define MWM_INPUT_FULL_APPLICATION_MODAL    3
57 
58 #define PROP_MWM_HINTS_ELEMENTS             5
59 #define PROP_MWM_HINTS_ELEMENTS_MIN         4
60 
61 static EX_Atom      _MOTIF_WM_HINTS = 0;
62 
63 /* Motif window hints */
64 typedef struct {
65    unsigned int        flags;
66    unsigned int        functions;
67    unsigned int        decorations;
68    unsigned int        inputMode;
69    unsigned int        status;
70 } MWMHints;
71 
72 void
MWM_GetHints(EWin * ewin,EX_Atom atom_change)73 MWM_GetHints(EWin * ewin, EX_Atom atom_change)
74 {
75    int                 num;
76    MWMHints            mhs, *mwmhints = &mhs;
77 
78    if (EwinIsInternal(ewin))
79       return;
80 
81    if (!_MOTIF_WM_HINTS)
82       _MOTIF_WM_HINTS = ex_atom_get("_MOTIF_WM_HINTS");
83 
84    if (atom_change && atom_change != _MOTIF_WM_HINTS)
85       return;
86 
87    ewin->mwm.valid = 1;
88    ewin->mwm.decor_border = 1;
89    ewin->mwm.decor_resizeh = 1;
90    ewin->mwm.decor_title = 1;
91    ewin->mwm.decor_menu = 1;
92    ewin->mwm.decor_minimize = 1;
93    ewin->mwm.decor_maximize = 1;
94    ewin->mwm.func_resize = 1;
95    ewin->mwm.func_move = 1;
96    ewin->mwm.func_minimize = 1;
97    ewin->mwm.func_maximize = 1;
98    ewin->mwm.func_close = 1;
99 
100    num = ex_window_prop_xid_get(EwinGetClientXwin(ewin), _MOTIF_WM_HINTS,
101 				_MOTIF_WM_HINTS, &mhs.flags, 5);
102    if (num < PROP_MWM_HINTS_ELEMENTS_MIN)
103       return;
104 
105    if (mwmhints->flags & MWM_HINTS_DECORATIONS)
106      {
107 	ewin->mwm.decor_border = 0;
108 	ewin->mwm.decor_resizeh = 0;
109 	ewin->mwm.decor_title = 0;
110 	ewin->mwm.decor_menu = 0;
111 	ewin->mwm.decor_minimize = 0;
112 	ewin->mwm.decor_maximize = 0;
113 	if (mwmhints->decorations & MWM_DECOR_ALL)
114 	  {
115 	     ewin->mwm.decor_border = 1;
116 	     ewin->mwm.decor_resizeh = 1;
117 	     ewin->mwm.decor_title = 1;
118 	     ewin->mwm.decor_menu = 1;
119 	     ewin->mwm.decor_minimize = 1;
120 	     ewin->mwm.decor_maximize = 1;
121 	  }
122 	if (mwmhints->decorations & MWM_DECOR_BORDER)
123 	   ewin->mwm.decor_border = 1;
124 	if (mwmhints->decorations & MWM_DECOR_RESIZEH)
125 	   ewin->mwm.decor_resizeh = 1;
126 	if (mwmhints->decorations & MWM_DECOR_TITLE)
127 	   ewin->mwm.decor_title = 1;
128 	if (mwmhints->decorations & MWM_DECOR_MENU)
129 	   ewin->mwm.decor_menu = 1;
130 	if (mwmhints->decorations & MWM_DECOR_MINIMIZE)
131 	   ewin->mwm.decor_minimize = 1;
132 	if (mwmhints->decorations & MWM_DECOR_MAXIMIZE)
133 	   ewin->mwm.decor_maximize = 1;
134      }
135 
136    if (mwmhints->flags & MWM_HINTS_FUNCTIONS)
137      {
138 	ewin->mwm.func_resize = 0;
139 	ewin->mwm.func_move = 0;
140 	ewin->mwm.func_minimize = 0;
141 	ewin->mwm.func_maximize = 0;
142 	ewin->mwm.func_close = 0;
143 	if (mwmhints->functions & MWM_FUNC_ALL)
144 	  {
145 	     ewin->mwm.func_resize = 1;
146 	     ewin->mwm.func_move = 1;
147 	     ewin->mwm.func_minimize = 1;
148 	     ewin->mwm.func_maximize = 1;
149 	     ewin->mwm.func_close = 1;
150 	  }
151 	if (mwmhints->functions & MWM_FUNC_RESIZE)
152 	   ewin->mwm.func_resize = 1;
153 	if (mwmhints->functions & MWM_FUNC_MOVE)
154 	   ewin->mwm.func_move = 1;
155 	if (mwmhints->functions & MWM_FUNC_MINIMIZE)
156 	   ewin->mwm.func_minimize = 1;
157 	if (mwmhints->functions & MWM_FUNC_MAXIMIZE)
158 	   ewin->mwm.func_maximize = 1;
159 	if (mwmhints->functions & MWM_FUNC_CLOSE)
160 	   ewin->mwm.func_close = 1;
161      }
162 
163    if (!ewin->mwm.decor_title && !ewin->mwm.decor_border)
164       ewin->props.no_border = 1;
165 }
166 
167 void
MWM_SetInfo(void)168 MWM_SetInfo(void)
169 {
170    EX_Atom             atom;
171    EX_Window           xwin;
172    EX_ID               mwminfo[2];
173 
174    atom = ex_atom_get("_MOTIF_WM_INFO");
175    xwin = WinGetXwin(VROOT);
176    mwminfo[0] = 2;
177    mwminfo[1] = xwin;
178    ex_window_prop_xid_set(xwin, atom, atom, mwminfo, 2);
179 }
180