2 * openlook.c - OPEN LOOK (tm) compatibility stuff
4 * Window Maker window manager
6 * Copyright (c) 1998-2002 Alfredo K. Kojima
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25 * Semantics and hint information taken from olwm code
34 #include <X11/Xutil.h>
35 #include <X11/Xatom.h>
42 #include "WindowMaker.h"
47 #include "properties.h"
60 #define OL_DECORATION_HEADER (1<<0)
61 #define OL_DECORATION_FOOTER (1<<1)
62 #define OL_DECORATION_PUSHPIN (1<<2)
63 #define OL_DECORATION_CLOSEBUTTON (1<<3)
64 #define OL_DECORATION_RESIZEABLE (1<<4)
65 #define OL_DECORATION_ICONNAME (1<<5)
66 #define OL_DECORATION_WARPTOPIN (1<<6)
67 #define OL_DECORATION_NONE (1<<7)
79 #define OL_WINTYPE (1<<0)
80 #define OL_MENUTYPE (1<<1)
81 #define OL_PINSTATE (1<<2)
82 #define OL_CANCEL (1<<3)
91 unsigned semantic_compose
:1;
92 unsigned semantic_capslock
:1;
93 unsigned semantic_numlock
:1;
94 unsigned semantic_scrolllock
:1;
98 static Atom _XA_SUN_WM_PROTOCOLS
= 0;
102 getWindowState(Window win
, OLWindowState
*state
)
104 static Atom _XA_SUN_WINDOW_STATE
= 0;
107 if (!_XA_SUN_WINDOW_STATE
) {
108 _XA_SUN_WINDOW_STATE
= XInternAtom(dpy
, "_SUN_WINDOW_STATE", False
);
111 data
= (unsigned long*)PropGetCheckProperty(win
, _XA_SUN_WINDOW_STATE
,
112 XA_INTEGER
, 32, 2, NULL
);
118 state
->flags
= data
[0];
119 state
->state
= data
[1];
128 getWindowHints(Window window
, OLHints
*hints
)
132 static Atom _XA_OL_WIN_ATTR
= 0;
134 if (!_XA_OL_WIN_ATTR
) {
135 _XA_OL_WIN_ATTR
= XInternAtom(dpy
, "_OL_WIN_ATTR", False
);
138 data
= (long*)PropGetCheckProperty(window
, _XA_OL_WIN_ATTR
,
139 _XA_OL_WIN_ATTR
, 32, 0, &count
);
147 hints
->flags
= OL_WINTYPE
|OL_MENUTYPE
|OL_PINSTATE
;
148 hints
->winType
= data
[0];
149 hints
->menuType
= data
[1];
150 hints
->pinInitState
= data
[2];
153 } else if (count
== 5) {
156 hints
->flags
= data
[0];
157 hints
->winType
= data
[1];
158 hints
->menuType
= data
[2];
159 hints
->pinInitState
= data
[3];
160 hints
->cancel
= data
[4];
169 /* do backward compatibility stuff */
170 if (hints
->flags
& OL_PINSTATE
) {
171 static Atom pinIn
= 0, pinOut
;
174 pinIn
= XInternAtom(dpy
, "_OL_PIN_IN", False
);
175 pinOut
= XInternAtom(dpy
, "_OL_PIN_OUT", False
);
178 if (hints
->pinInitState
== pinIn
)
179 hints
->pinInitState
= OL_PIN_IN
;
180 else if (hints
->pinInitState
== pinOut
)
181 hints
->pinInitState
= OL_PIN_OUT
;
191 applyDecorationHints(Window win
, int *flags
)
194 static Atom _XA_OL_DECOR_ADD
= 0;
195 static Atom _XA_OL_DECOR_DEL
= 0;
196 static Atom _XA_CLOSE
, _XA_FOOTER
, _XA_RESIZE
, _XA_HEADER
, _XA_PIN
,
201 if (!_XA_OL_DECOR_DEL
) {
202 _XA_OL_DECOR_ADD
= XInternAtom(dpy
, "_OL_DECOR_ADD", False
);
203 _XA_OL_DECOR_DEL
= XInternAtom(dpy
, "_OL_DECOR_DEL", False
);
205 _XA_CLOSE
= XInternAtom(dpy
, "_OL_DECOR_CLOSE", False
);
206 _XA_FOOTER
= XInternAtom(dpy
, "_OL_DECOR_FOOTER", False
);
207 _XA_RESIZE
= XInternAtom(dpy
, "_OL_DECOR_RESIZE", False
);
208 _XA_HEADER
= XInternAtom(dpy
, "_OL_DECOR_HEADER", False
);
209 _XA_PIN
= XInternAtom(dpy
, "_OL_DECOR_PIN", False
);
210 _XA_ICONNAME
= XInternAtom(dpy
, "_OL_DECOR_ICON_NAME", False
);
213 atoms
= (Atom
*)PropGetCheckProperty(win
, _XA_OL_DECOR_ADD
, XA_ATOM
, 32, 0,
216 for (i
=0; i
< count
; i
++) {
217 if (atoms
[i
] == _XA_CLOSE
)
218 *flags
|= OL_DECORATION_CLOSEBUTTON
;
219 else if (atoms
[i
] == _XA_FOOTER
)
220 *flags
|= OL_DECORATION_FOOTER
;
221 else if (atoms
[i
] == _XA_RESIZE
)
222 *flags
|= OL_DECORATION_RESIZEABLE
;
223 else if (atoms
[i
] == _XA_HEADER
)
224 *flags
|= OL_DECORATION_HEADER
;
225 else if (atoms
[i
] == _XA_PIN
)
226 *flags
|= OL_DECORATION_PUSHPIN
;
227 else if (atoms
[i
] == _XA_ICONNAME
)
228 *flags
|= OL_DECORATION_ICONNAME
;
233 atoms
= (Atom
*)PropGetCheckProperty(win
, _XA_OL_DECOR_DEL
, XA_ATOM
, 32, 0,
236 for (i
=0; i
< count
; i
++) {
237 if (atoms
[i
] == _XA_CLOSE
)
238 *flags
&= ~OL_DECORATION_CLOSEBUTTON
;
239 else if (atoms
[i
] == _XA_FOOTER
)
240 *flags
&= ~OL_DECORATION_FOOTER
;
241 else if (atoms
[i
] == _XA_RESIZE
)
242 *flags
&= ~OL_DECORATION_RESIZEABLE
;
243 else if (atoms
[i
] == _XA_HEADER
)
244 *flags
&= ~OL_DECORATION_HEADER
;
245 else if (atoms
[i
] == _XA_PIN
)
246 *flags
&= ~OL_DECORATION_PUSHPIN
;
247 else if (atoms
[i
] == _XA_ICONNAME
)
248 *flags
&= ~OL_DECORATION_ICONNAME
;
256 wOLWMInitStuff(WScreen
*scr
)
258 static Atom _SUN_OL_WIN_ATTR_5
;
260 if (!_XA_SUN_WM_PROTOCOLS
) {
261 _XA_SUN_WM_PROTOCOLS
= XInternAtom(dpy
, "_SUN_WM_PROTOCOLS", False
);
262 _SUN_OL_WIN_ATTR_5
= XInternAtom(dpy
, "_SUN_OL_WIN_ATTR_5", False
);
265 XChangeProperty(dpy
, scr
->root_win
, _XA_SUN_WM_PROTOCOLS
, XA_ATOM
, 32,
266 PropModeReplace
, (unsigned char*)&_SUN_OL_WIN_ATTR_5
, 1);
271 wOLWMChangePushpinState(WWindow
*wwin
, Bool state
)
273 static Atom pinState
= 0;
276 pinState
= XInternAtom(dpy
, "_OL_PIN_STATE", False
);
279 XChangeProperty(dpy
, wwin
->client_win
, pinState
, XA_INTEGER
, 32,
280 PropModeReplace
, (unsigned char *)&state
, 1);
285 wOLWMShutdown(WScreen
*scr
)
287 XDeleteProperty(dpy
, scr
->root_win
, _XA_SUN_WM_PROTOCOLS
);
293 wOLWMUpdateWindowState(WWindow
*wwin
)
295 if (wwin
->ol_window_state
.used
) {
296 if (wwin
->ol_window_state
.semantic
) {
297 if (wwin
->ol_window_state
.semantic_compose
)
300 setComposeLed(False
);
303 setComposeLed(False
);
306 #endif /* unfinished */
309 wOLWMCheckClientHints(WWindow
*wwin
)
312 static Atom WT_BASE
= 0, WT_CMD
, WT_NOTICE
, WT_HELP
, WT_OTHER
;
313 static Atom MT_FULL
, MT_LIMITED
, MT_NONE
;
315 int pinInitState
= OL_PIN_IN
;
319 WT_BASE
= XInternAtom(dpy
, "_OL_WT_BASE", False
);
320 WT_CMD
= XInternAtom(dpy
, "_OL_WT_CMD", False
);
321 WT_NOTICE
= XInternAtom(dpy
, "_OL_WT_NOTICE", False
);
322 WT_HELP
= XInternAtom(dpy
, "_OL_WT_HELP", False
);
323 WT_OTHER
= XInternAtom(dpy
, "_OL_WT_OTHER", False
);
325 MT_FULL
= XInternAtom(dpy
, "_OL_MENU_FULL", False
);
326 MT_LIMITED
= XInternAtom(dpy
, "_OL_MENU_LIMITED", False
);
327 MT_NONE
= XInternAtom(dpy
, "_OL_NONE", False
);
332 if (!getWindowHints(wwin
->client_win
, &hints
) ||
333 !(hints
.flags
& OL_WINTYPE
)) {
335 decoration
= OL_DECORATION_CLOSEBUTTON
|OL_DECORATION_RESIZEABLE
336 |OL_DECORATION_HEADER
|OL_DECORATION_ICONNAME
;
341 if (hints
.winType
== WT_BASE
) {
343 decoration
= OL_DECORATION_CLOSEBUTTON
|OL_DECORATION_RESIZEABLE
344 |OL_DECORATION_HEADER
|OL_DECORATION_ICONNAME
;
348 } else if (hints
.winType
== WT_CMD
) {
350 decoration
= OL_DECORATION_PUSHPIN
|OL_DECORATION_RESIZEABLE
351 |OL_DECORATION_HEADER
|OL_DECORATION_ICONNAME
;
353 menuType
= MT_LIMITED
;
355 } else if (hints
.winType
== WT_NOTICE
) {
357 decoration
= OL_DECORATION_ICONNAME
;
360 } else if (hints
.winType
== WT_HELP
) {
362 decoration
= OL_DECORATION_PUSHPIN
|OL_DECORATION_HEADER
363 |OL_DECORATION_ICONNAME
|OL_DECORATION_WARPTOPIN
;
364 menuType
= MT_LIMITED
;
366 } else if (hints
.winType
== WT_OTHER
) {
368 decoration
= OL_DECORATION_ICONNAME
;
371 if (hints
.flags
& OL_MENUTYPE
) {
372 menuType
= hints
.menuType
;
376 if (hints
.flags
& OL_PINSTATE
) {
377 pinInitState
= hints
.pinInitState
;
379 pinInitState
= OL_PIN_OUT
;
383 /* mask attributes with decoration hints */
384 applyDecorationHints(wwin
->client_win
, &decoration
);
386 if ((decoration
& OL_DECORATION_CLOSEBUTTON
)
387 && (decoration
& OL_DECORATION_PUSHPIN
))
388 decoration
&= ~OL_DECORATION_CLOSEBUTTON
;
390 if (!(decoration
& OL_DECORATION_PUSHPIN
))
391 decoration
&= ~OL_DECORATION_WARPTOPIN
;
394 /* map the hints to our attributes */
395 if (menuType
== MT_FULL
)
396 wwin
->flags
.olwm_limit_menu
= 0;
398 wwin
->flags
.olwm_limit_menu
= 1;
400 /* this is a transient-like window */
401 if (hints
.winType
== WT_CMD
) {
402 wwin
->client_flags
.olwm_transient
= 1;
406 * Emulate olwm pushpin.
407 * If the initial state of the pin is in, then put the normal close
408 * button. If not, make the close button different and when the
409 * user moves the window or clicks in the close button, turn it
410 * into a normal close button.
412 if ((decoration
& OL_DECORATION_PUSHPIN
) && pinInitState
==OL_PIN_OUT
) {
413 wwin
->flags
.olwm_push_pin_out
= 1;
415 wOLWMChangePushpinState(wwin
, False
);
417 wOLWMChangePushpinState(wwin
, True
);
420 if (!(decoration
& OL_DECORATION_RESIZEABLE
)) {
421 wwin
->client_flags
.no_resizable
= 1;
422 wwin
->client_flags
.no_resizebar
= 1;
425 if (decoration
& OL_DECORATION_WARPTOPIN
) {
426 wwin
->client_flags
.olwm_warp_to_pin
= 1;