- Fixed dock's menu mapping position when dock is on the right side.
[wmaker-crm.git] / src / openlook.c
blob6ce136571d0b70882486e437a93045fb6488b766
1 /*
2 * openlook.c - OPEN LOOK (tm) compatibility stuff
3 *
4 * Window Maker window manager
5 *
6 * Copyright (c) 1998-2002 Alfredo K. Kojima
7 *
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,
21 * USA.
25 * Semantics and hint information taken from olwm code
28 #include "wconfig.h"
30 #ifdef OLWM_HINTS
33 #include <X11/Xlib.h>
34 #include <X11/Xutil.h>
35 #include <X11/Xatom.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <string.h>
42 #include "WindowMaker.h"
44 #include "wcore.h"
45 #include "framewin.h"
46 #include "window.h"
47 #include "properties.h"
48 #include "icon.h"
49 #include "client.h"
50 #include "funcs.h"
52 #include "openlook.h"
55 /* pin states */
56 #define OL_PIN_OUT 0
57 #define OL_PIN_IN 1
59 /* flags */
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)
71 typedef struct {
72 long flags;
73 Atom winType;
74 Atom menuType;
75 long pinInitState;
76 long cancel;
77 } OLHints;
79 #define OL_WINTYPE (1<<0)
80 #define OL_MENUTYPE (1<<1)
81 #define OL_PINSTATE (1<<2)
82 #define OL_CANCEL (1<<3)
86 typedef struct {
87 unsigned used:1;
89 unsigned semantic:1;
91 unsigned semantic_compose:1;
92 unsigned semantic_capslock:1;
93 unsigned semantic_numlock:1;
94 unsigned semantic_scrolllock:1;
95 } WOLWindowState;
98 static Atom _XA_SUN_WM_PROTOCOLS = 0;
100 #ifdef unused
101 static Bool
102 getWindowState(Window win, OLWindowState *state)
104 static Atom _XA_SUN_WINDOW_STATE = 0;
105 unsigned long *data;
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);
114 if (!data) {
115 return False;
118 state->flags = data[0];
119 state->state = data[1];
121 XFree(data);
123 return True;
125 #endif
127 static Bool
128 getWindowHints(Window window, OLHints *hints)
130 long *data;
131 int count;
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);
141 if (!data)
142 return False;
144 if (count == 3) {
145 /* old format */
147 hints->flags = OL_WINTYPE|OL_MENUTYPE|OL_PINSTATE;
148 hints->winType = data[0];
149 hints->menuType = data[1];
150 hints->pinInitState = data[2];
151 hints->cancel = 0;
153 } else if (count == 5) {
154 /* new format */
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];
162 } else {
163 XFree(data);
164 return False;
167 XFree(data);
169 /* do backward compatibility stuff */
170 if (hints->flags & OL_PINSTATE) {
171 static Atom pinIn = 0, pinOut;
173 if (!pinIn) {
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;
184 return True;
190 static void
191 applyDecorationHints(Window win, int *flags)
193 Atom *atoms;
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,
197 _XA_ICONNAME;
198 int count;
199 int i;
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,
214 &count);
215 if (atoms) {
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;
230 XFree(atoms);
233 atoms = (Atom*)PropGetCheckProperty(win, _XA_OL_DECOR_DEL, XA_ATOM, 32, 0,
234 &count);
235 if (atoms) {
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;
250 XFree(atoms);
255 void
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);
270 void
271 wOLWMChangePushpinState(WWindow *wwin, Bool state)
273 static Atom pinState = 0;
275 if (!pinState) {
276 pinState = XInternAtom(dpy, "_OL_PIN_STATE", False);
279 XChangeProperty(dpy, wwin->client_win, pinState, XA_INTEGER, 32,
280 PropModeReplace, (unsigned char *)&state, 1);
284 void
285 wOLWMShutdown(WScreen *scr)
287 XDeleteProperty(dpy, scr->root_win, _XA_SUN_WM_PROTOCOLS);
291 #ifdef unfinished
292 void
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)
298 setComposeLed(True);
299 else
300 setComposeLed(False);
302 } else {
303 setComposeLed(False);
306 #endif /* unfinished */
308 void
309 wOLWMCheckClientHints(WWindow *wwin)
311 OLHints hints;
312 static Atom WT_BASE = 0, WT_CMD, WT_NOTICE, WT_HELP, WT_OTHER;
313 static Atom MT_FULL, MT_LIMITED, MT_NONE;
314 int decoration;
315 int pinInitState = OL_PIN_IN;
316 Atom menuType;
318 if (!WT_BASE) {
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);
330 /* get attributes */
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;
338 menuType = MT_FULL;
340 } else {
341 if (hints.winType == WT_BASE) {
343 decoration = OL_DECORATION_CLOSEBUTTON|OL_DECORATION_RESIZEABLE
344 |OL_DECORATION_HEADER|OL_DECORATION_ICONNAME;
346 menuType = MT_FULL;
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;
358 menuType = MT_NONE;
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;
369 menuType = MT_NONE;
371 if (hints.flags & OL_MENUTYPE) {
372 menuType = hints.menuType;
376 if (hints.flags & OL_PINSTATE) {
377 pinInitState = hints.pinInitState;
378 } else {
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;
397 else
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);
416 } else {
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;
430 #endif