Code update for Window Maker version 0.50.0
[wmaker-crm.git] / src / openlook.c
blobea0dc10d3df18d15f2ba3cd989663d7f56ffbccc
1 /*
2 * openlook.c - OPEN LOOK (tm) compatibility stuff
3 *
4 * Window Maker window manager
5 *
6 * Copyright (c) 1998 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 * based on olwm code
28 #include "wconfig.h"
30 #ifdef OLWM_HINTS
33 #include <X11/Xlib.h>
34 #include <X11/Xutil.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <string.h>
41 #include "WindowMaker.h"
43 #include "wcore.h"
44 #include "framewin.h"
45 #include "window.h"
46 #include "properties.h"
47 #include "icon.h"
48 #include "client.h"
49 #include "funcs.h"
51 #include "openlook.h"
54 /* pin states */
55 #define OL_PIN_OUT 0
56 #define OL_PIN_IN 1
58 /* flags */
59 #define OL_DECORATION_HEADER (1<<0)
60 #define OL_DECORATION_FOOTER (1<<1)
61 #define OL_DECORATION_PUSHPIN (1<<2)
62 #define OL_DECORATION_CLOSEBUTTON (1<<3)
63 #define OL_DECORATION_RESIZEABLE (1<<4)
64 #define OL_DECORATION_ICONNAME (1<<5)
65 #define OL_DECORATION_WARPTOPIN (1<<6)
66 #define OL_DECORATION_NONE (1<<7)
70 typedef struct {
71 long flags;
72 Atom winType;
73 Atom menuType;
74 long pinInitState;
75 long cancel;
76 } OLHints;
78 #define OL_WINTYPE (1<<0)
79 #define OL_MENUTYPE (1<<1)
80 #define OL_PINSTATE (1<<2)
81 #define OL_CANCEL (1<<3)
85 typedef struct {
86 unsigned long flags;
87 unsigned long state;
88 } OLWindowState;
90 #define OL_STATE_SEMANTIC (1<<0)
92 #define OL_STATE_COMPOSE (1<<0)
93 #define OL_STATE_CAPSLOCK (1<<1)
94 #define OL_STATE_NUMLOCK (1<<2)
95 #define OL_STATE_SCROLLLOCK (1<<3)
98 static Atom _XA_SUN_WM_PROTOCOLS = 0;
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;
127 static Bool
128 getWindowHints(Window window, OLHints *hints)
130 long *data;
131 int count;
133 if (!_XA_OL_WIN_ATTR) {
134 _XA_OL_WIN_ATTR = XInternAtom(dpy, "_OL_WIN_ATTR", False);
137 data = (long*)PropGetCheckProperty(window, _XA_OL_WIN_ATTR,
138 _XA_OL_WIN_ATTR, 32, 0, &count);
140 if (!data)
141 return False;
143 if (count == 3) {
144 /* old format */
146 hints->flags = OL_WINTYPE|OL_MENUTYPE|OL_PINSTATE;
147 hints->winType = data[0];
148 hints->menuType = data[1];
149 hints->pinInitState = data[2];
150 hints->cancel = 0;
152 } else if (count == 5) {
153 /* new format */
155 hints->flags = data[0];
156 hints->winType = data[1];
157 hints->menuType = data[2];
158 hints->pinInitState = data[3];
159 hints->cancel = data[4];
161 } else {
162 XFree(data);
163 return False;
166 XFree(data);
168 /* do backward compatibility stuff */
169 if (hints->flags & OL_PINSTATE) {
170 static Atom pinIn = 0, pinOut;
172 if (!pinIn) {
173 pinIn = XInternAtom(dpy, "_OL_PIN_IN", False);
174 pinOut = XInternAtom(dpy, "_OL_PIN_OUT", False);
177 if (hints->pinInitState == pinIn)
178 hints->pinInitState = OL_PIN_IN;
179 else if (hints->pinInitState == pinOut)
180 hints->pinInitState = OL_PIN_OUT;
183 return True;
189 static void
190 applyDecorationHints(Window win, int *flags)
192 Atom *atoms;
193 static Atom _XA_OL_DECOR_ADD = 0;
194 static Atom _XA_OL_DECOR_DEL = 0;
195 static Atom _XA_CLOSE, _XA_FOOTER, _XA_RESIZE, _XA_HEADER, _XA_PIN,
196 _XA_ICONNAME;
197 int count;
198 int i;
200 if (!_XA_OL_DECOR_DEL) {
201 _XA_OL_DECOR_ADD = XInternAtom(dpy, "_OL_DECOR_ADD", False);
202 _XA_OL_DECOR_DEL = XInternAtom(dpy, "_OL_DECOR_DEL", False);
204 _XA_CLOSE = XInternAtom(dpy, "_OL_DECOR_CLOSE", False);
205 _XA_FOOTER = XInternAtom(dpy, "_OL_DECOR_FOOTER", False);
206 _XA_RESIZE = XInternAtom(dpy, "_OL_DECOR_RESIZE", False);
207 _XA_HEADER = XInternAtom(dpy, "_OL_DECOR_HEADER", False);
208 _XA_PIN = XInternAtom(dpy, "_OL_DECOR_PIN", False);
209 _XA_ICONNAME = XInternAtom(dpy, "_OL_DECOR_ICON_NAME", False);
212 atoms = PropGetCheckProperty(win, _XA_OL_DECOR_ADD, XA_ATOM, 32, 0,
213 &count);
214 if (atoms) {
215 for (i=0; i < count; i++) {
216 if (atoms[i] == _XA_CLOSE)
217 *flags |= OL_DECORATION_CLOSEBUTTON;
218 else if (atoms[i] == _XA_FOOTER)
219 *flags |= OL_DECORATION_FOOTER;
220 else if (atoms[i] == _XA_RESIZE)
221 *flags |= OL_DECORATION_RESIZEABLE;
222 else if (atoms[i] == _XA_HEADER)
223 *flags |= OL_DECORATION_HEADER;
224 else if (atoms[i] == _XA_PIN)
225 *flags |= OL_DECORATION_PUSHPIN;
226 else if (atoms[i] == _XA_ICONNAME)
227 *flags |= OL_DECORATION_ICONNAME;
229 XFree(atoms);
232 atoms = PropGetCheckProperty(win, _XA_OL_DECOR_DEL, XA_ATOM, 32, 0,
233 &count);
234 if (atoms) {
235 for (i=0; i < count; i++) {
236 if (atoms[i] == _XA_CLOSE)
237 *flags &= ~OL_DECORATION_CLOSEBUTTON;
238 else if (atoms[i] == _XA_FOOTER)
239 *flags &= ~OL_DECORATION_FOOTER;
240 else if (atoms[i] == _XA_RESIZE)
241 *flags &= ~OL_DECORATION_RESIZEABLE;
242 else if (atoms[i] == _XA_HEADER)
243 *flags &= ~OL_DECORATION_HEADER;
244 else if (atoms[i] == _XA_PIN)
245 *flags &= ~OL_DECORATION_PUSHPIN;
246 else if (atoms[i] == _XA_ICONNAME)
247 *flags &= ~OL_DECORATION_ICONNAME;
249 XFree(atoms);
254 void
255 wOLWMInitStuff(WScreen *scr)
257 static Atom _SUN_OL_WIN_ATTR_5;
259 if (!_XA_SUN_WM_PROTOCOLS) {
260 _XA_SUN_WM_PROTOCOLS = XInternAtom(dpy, "_SUN_WM_PROTOCOLS", False);
261 _SUN_OL_WIN_ATTR_5 = XInternAtom(dpy, "_SUN_OL_WIN_ATTR_5", False);
264 XChangeProperty(dpy, scr->root_win, _XA_SUN_WM_PROTOCOLS, XA_ATOM, 32,
265 PropModeReplace, (unsigned char*)&_SUN_OL_WIN_ATTR_5, 1);
269 void
270 wOLWMShutdown(WScreen *scr)
272 XDeleteProperty(dpy, scr->root_win, _XA_SUN_WM_PROTOCOLS);
276 void
277 wOLWMCheckClientHints(WWindow *wwin)
279 OLHints hints;
280 static Atom WT_BASE = 0, WT_CMD, WT_NOTICE, WT_HELP, WT_OTHER;
281 static Atom MT_FULL, MT_LIMITED, MT_NONE;
282 int decorations;
283 int pinInitState = OL_PIN_IN;
284 Atom menuType;
286 if (!WT_BASE) {
287 WT_BASE = XInternAtom(dpy, "_OL_WT_BASE", False);
288 WT_CMD = XInternAtom(dpy, "_OL_WT_CMD", False);
289 WT_NOTICE = XInternAtom(dpy, "_OL_WT_NOTICE", False);
290 WT_HELP = XInternAtom(dpy, "_OL_WT_HELP", False);
291 WT_OTHER = XInternAtom(dpy, "_OL_WT_OTHER", False);
293 MT_FULL = XInternAtom(dpy, "_OL_MENU_FULL", False);
294 MT_LIMITED = XInternAtom(dpy, "_OL_MENU_LIMITED", False);
295 MT_NONE = XInternAtom(dpy, "_OL_NONE", False);
298 /* get attributes */
300 if (!getWindowHints(wwin->client_win, &hints) ||
301 !(hints.flags & OL_WINTYPE)) {
303 decorations = OL_DECORATION_CLOSEBUTTON|OL_DECORATION_RESIZEABLE
304 |OL_DECORATION_HEADER|OL_DECORATION_ICONNAME;
306 menuType = MT_FULL;
308 } else {
309 if (hints.winType == WT_BASE) {
311 decorations = OL_DECORATION_CLOSEBUTTON|OL_DECORATION_RESIZEABLE
312 |OL_DECORATION_HEADER|OL_DECORATION_ICONNAME;
314 menuType = MT_FULL;
316 } else if (hints.winType == WT_CMD) {
318 decorations = OL_DECORATION_PUSHPIN|OL_DECORATION_RESIZEABLE
319 |OL_DECORATION_HEADER|OL_DECORATION_ICONNAME;
321 menuType = MT_LIMITED;
323 } else if (hints.winType == WT_NOTICE) {
325 decorations = OL_DECORATION_ICONNAME;
326 menuType = MT_NONE;
328 } else if (hints.winType == WT_HELP) {
330 decorations = OL_DECORATION_PUSHPIN|OL_DECORATION_HEADER
331 |OL_DECORATION_ICONNAME|OL_DECORATION_WARPTOPIN;
332 menuType = MT_LIMITED;
334 } else if (hints.winType == WT_OTHER) {
336 decorations = OL_DECORATION_ICONNAME;
337 menuType = MT_NONE;
339 if (hints.flags & OL_MENUTYPE) {
340 menuType = hints.menuType;
344 if (hints.flags & OL_PINSTATE) {
345 pinInitState = hints.pinInitState;
346 } else {
347 pinInitState = OL_PIN_OUT;
351 /* mask attributes with decoration hints */
352 applyDecorationHints(wwin->client_win, &decoration);
354 if ((decoration & OL_DECORATION_CLOSEBUTTON)
355 && (decoration & OL_DECORATION_PUSHPIN))
356 decoration &= ~OL_DECORATION_CLOSEBUTTON;
358 if (!(decoration & OL_DECORATION_PUSHPIN))
359 decoration &= ~OL_DECORATION_WARPTOPIN;
362 /* map the hints to our attributes */
363 if (menuType == MT_FULL)
364 wwin->flags.olwm_limit_menu = 0;
365 else
366 wwin->flags.olwm_limit_menu = 1;
369 * Emulate olwm pushpin.
370 * If the initial state of the pin is in, then put the normal close
371 * button. If not, make the close button different and when the
372 * user moves the window or clicks in the close button, turn it
373 * into a normal close button.
375 if ((decoration & OL_DECORATION_PUSHPIN) && pinInitState==OL_PIN_OUT) {
376 wwin->flags.olwm_push_pin = 1;
383 #endif