- Fixed dock's menu mapping position when dock is on the right side.
[wmaker-crm.git] / src / properties.c
blob1b84f6c4f40d6f2da7fb60d7a181828f0eac31f7
1 /*
2 * Window Maker window manager
3 *
4 * Copyright (c) 1997-2002 Alfredo K. Kojima
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 * USA.
22 #include "wconfig.h"
24 #include <X11/Xlib.h>
25 #include <X11/Xutil.h>
26 #include <X11/Xatom.h>
27 #include <string.h>
28 #include <stdlib.h>
30 #include "WindowMaker.h"
31 #include "window.h"
32 #include "GNUstep.h"
35 /* atoms */
36 extern Atom _XA_WM_STATE;
37 extern Atom _XA_WM_CHANGE_STATE;
38 extern Atom _XA_WM_PROTOCOLS;
39 extern Atom _XA_WM_CLIENT_LEADER;
40 extern Atom _XA_WM_TAKE_FOCUS;
41 extern Atom _XA_WM_DELETE_WINDOW;
42 extern Atom _XA_WM_SAVE_YOURSELF;
43 #ifdef XSMP_ENABLED
44 extern Atom _XA_WM_WINDOW_ROLE;
45 extern Atom _XA_SM_CLIENT_ID;
46 #endif
49 extern Atom _XA_GNUSTEP_WM_ATTR;
50 extern Atom _XA_GNUSTEP_WM_MINIATURIZE_WINDOW;
52 extern Atom _XA_WINDOWMAKER_WM_FUNCTION;
53 extern Atom _XA_WINDOWMAKER_MENU;
54 extern Atom _XA_WINDOWMAKER_WM_PROTOCOLS;
55 extern Atom _XA_WINDOWMAKER_NOTICEBOARD;
56 extern Atom _XA_WINDOWMAKER_ICON_TILE;
57 extern Atom _XA_WINDOWMAKER_ICON_SIZE;
59 int
60 PropGetNormalHints(Window window, XSizeHints *size_hints, int *pre_iccm)
62 long supplied_hints;
64 if (!XGetWMNormalHints(dpy, window, size_hints, &supplied_hints)) {
65 return False;
67 if (supplied_hints==(USPosition|USSize|PPosition|PSize|PMinSize|PMaxSize
68 |PResizeInc|PAspect)) {
69 *pre_iccm = 1;
70 } else {
71 *pre_iccm = 0;
73 return True;
77 int
78 PropGetWMClass(Window window, char **wm_class, char **wm_instance)
80 XClassHint *class_hint;
82 class_hint = XAllocClassHint();
83 if (XGetClassHint(dpy,window,class_hint) == 0) {
84 *wm_class = NULL;
85 *wm_instance = NULL;
86 XFree(class_hint);
87 return False;
89 *wm_instance = class_hint->res_name;
90 *wm_class = class_hint->res_class;
92 XFree(class_hint);
93 return True;
97 void
98 PropGetProtocols(Window window, WProtocols *prots)
100 Atom *protocols;
101 int count, i;
103 memset(prots, 0, sizeof(WProtocols));
104 if (!XGetWMProtocols(dpy, window, &protocols, &count)) {
105 return;
107 for (i=0; i<count; i++) {
108 if (protocols[i]==_XA_WM_TAKE_FOCUS)
109 prots->TAKE_FOCUS=1;
110 else if (protocols[i]==_XA_WM_DELETE_WINDOW)
111 prots->DELETE_WINDOW=1;
112 else if (protocols[i]==_XA_WM_SAVE_YOURSELF)
113 prots->SAVE_YOURSELF=1;
114 else if (protocols[i]==_XA_GNUSTEP_WM_MINIATURIZE_WINDOW)
115 prots->MINIATURIZE_WINDOW=1;
117 XFree(protocols);
121 unsigned char*
122 PropGetCheckProperty(Window window, Atom hint, Atom type, int format,
123 int count, int *retCount)
125 Atom type_ret;
126 int fmt_ret;
127 unsigned long nitems_ret;
128 unsigned long bytes_after_ret;
129 unsigned char *data;
130 int tmp;
132 if (count <= 0)
133 tmp = 0xffffff;
134 else
135 tmp = count;
137 if (XGetWindowProperty(dpy, window, hint, 0, tmp, False, type,
138 &type_ret, &fmt_ret, &nitems_ret, &bytes_after_ret,
139 (unsigned char **)&data)!=Success || !data)
140 return NULL;
142 if ((type!=AnyPropertyType && type!=type_ret)
143 || (count > 0 && nitems_ret != count)
144 || (format != 0 && format != fmt_ret)) {
145 XFree(data);
146 return NULL;
149 if (retCount)
150 *retCount = nitems_ret;
152 return data;
157 PropGetGNUstepWMAttr(Window window, GNUstepWMAttributes **attr)
159 unsigned long *data;
161 data = (unsigned long*)PropGetCheckProperty(window, _XA_GNUSTEP_WM_ATTR,
162 _XA_GNUSTEP_WM_ATTR, 32, 9,
163 NULL);
165 if (!data)
166 return False;
168 *attr = malloc(sizeof(GNUstepWMAttributes));
169 if (!*attr) {
170 XFree(data);
171 return False;
173 (*attr)->flags = data[0];
174 (*attr)->window_style = data[1];
175 (*attr)->window_level = data[2];
176 (*attr)->reserved = data[3];
177 (*attr)->miniaturize_pixmap = data[4];
178 (*attr)->close_pixmap = data[5];
179 (*attr)->miniaturize_mask = data[6];
180 (*attr)->close_mask = data[7];
181 (*attr)->extra_flags = data[8];
183 XFree(data);
185 return True;
190 void
191 PropSetWMakerProtocols(Window root)
193 Atom protocols[3];
194 int count=0;
196 protocols[count++] = _XA_WINDOWMAKER_MENU;
197 protocols[count++] = _XA_WINDOWMAKER_WM_FUNCTION;
198 protocols[count++] = _XA_WINDOWMAKER_NOTICEBOARD;
200 XChangeProperty(dpy, root, _XA_WINDOWMAKER_WM_PROTOCOLS, XA_ATOM,
201 32, PropModeReplace, (unsigned char *)protocols, count);
205 void
206 PropSetIconTileHint(WScreen *scr, RImage *image)
208 static Atom imageAtom = 0;
209 unsigned char *tmp;
210 int x, y;
212 if (scr->info_window == None)
213 return;
215 if (!imageAtom) {
217 * WIDTH, HEIGHT (16 bits, MSB First)
218 * array of R,G,B,A bytes
220 imageAtom = XInternAtom(dpy, "_RGBA_IMAGE", False);
223 tmp = malloc(image->width * image->height * 4 + 4);
224 if (!tmp) {
225 wwarning("could not allocate memory to set _WINDOWMAKER_ICON_TILE hint");
226 return;
229 tmp[0] = image->width>>8;
230 tmp[1] = image->width&0xff;
231 tmp[2] = image->height>>8;
232 tmp[3] = image->height&0xff;
234 if (image->format == RRGBAFormat) {
235 memcpy(&tmp[4], image->data, image->width*image->height*4);
236 } else {
237 char *ptr = tmp+4;
238 char *src = image->data;
240 for (y = 0; y < image->height; y++) {
241 for (x = 0; x < image->width; x++) {
242 *ptr++ = *src++;
243 *ptr++ = *src++;
244 *ptr++ = *src++;
245 *ptr++ = 255;
250 XChangeProperty(dpy, scr->info_window, _XA_WINDOWMAKER_ICON_TILE,
251 imageAtom, 8, PropModeReplace, tmp,
252 image->width * image->height * 4 + 4);
253 wfree(tmp);
258 Window
259 PropGetClientLeader(Window window)
261 Window *win;
262 Window leader;
264 win = (Window*)PropGetCheckProperty(window, _XA_WM_CLIENT_LEADER,
265 XA_WINDOW, 32, 1, NULL);
267 if (!win)
268 return None;
270 leader = (Window)*win;
271 XFree(win);
273 return leader;
277 #ifdef XSMP_ENABLED
278 char*
279 PropGetClientID(Window window)
281 XTextProperty txprop;
283 txprop.value = NULL;
285 if (XGetTextProperty(dpy, window, &txprop, _XA_SM_CLIENT_ID)!=Success) {
286 return NULL;
289 if (txprop.encoding == XA_STRING && txprop.format == 8
290 && txprop.nitems > 0) {
292 return (char*)txprop.value;
293 } else {
295 if (txprop.value)
296 XFree(txprop.value);
298 return NULL;
303 char*
304 PropGetWindowRole(Window window)
306 XTextProperty txprop;
308 txprop.value = NULL;
310 if (XGetTextProperty(dpy, window, &txprop, _XA_WM_WINDOW_ROLE)!=Success) {
311 return NULL;
314 if (txprop.encoding == XA_STRING && txprop.format == 8
315 && txprop.nitems > 0) {
317 return (char*)txprop.value;
318 } else {
320 if (txprop.value)
321 XFree(txprop.value);
323 return NULL;
326 #endif /* XSMP_ENABLED */
329 void
330 PropWriteGNUstepWMAttr(Window window, GNUstepWMAttributes *attr)
332 unsigned long data[9];
334 data[0] = attr->flags;
335 data[1] = attr->window_style;
336 data[2] = attr->window_level;
337 data[3] = 0; /* reserved */
338 /* The X protocol says XIDs are 32bit */
339 data[4] = attr->miniaturize_pixmap;
340 data[5] = attr->close_pixmap;
341 data[6] = attr->miniaturize_mask;
342 data[7] = attr->close_mask;
343 data[8] = attr->extra_flags;
344 XChangeProperty(dpy, window, _XA_GNUSTEP_WM_ATTR, _XA_GNUSTEP_WM_ATTR,
345 32, PropModeReplace, (unsigned char *)data, 9);
350 PropGetWindowState(Window window)
352 long *data;
353 long state;
355 data = (long*)PropGetCheckProperty(window, _XA_WM_STATE, _XA_WM_STATE,
356 32, 1, NULL);
358 if (!data)
359 return -1;
361 state = *data;
362 XFree(data);
364 return state;
368 void
369 PropCleanUp(Window root)
371 XDeleteProperty(dpy, root, _XA_WINDOWMAKER_WM_PROTOCOLS);
373 XDeleteProperty(dpy, root, _XA_WINDOWMAKER_NOTICEBOARD);
375 XDeleteProperty(dpy, root, XA_WM_ICON_SIZE);
377 #ifdef KWM_HINTS
378 XDeleteProperty(dpy, root, XInternAtom(dpy, "KWM_RUNNING", False));
379 #endif