Avoid buffer overrun in parseMenuCommand.
[wmaker-crm.git] / src / properties.c
blob0442077dbf9992a492042dbbfb58d16eaf4422f4
1 /*
2 * Window Maker window manager
4 * Copyright (c) 1997-2003 Alfredo K. Kojima
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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "wconfig.h"
23 #include <X11/Xlib.h>
24 #include <X11/Xutil.h>
25 #include <X11/Xatom.h>
26 #include <string.h>
27 #include <stdlib.h>
29 #include "WindowMaker.h"
30 #include "window.h"
31 #include "GNUstep.h"
33 /* atoms */
34 extern Atom _XA_WM_STATE;
35 extern Atom _XA_WM_CLIENT_LEADER;
36 extern Atom _XA_WM_TAKE_FOCUS;
37 extern Atom _XA_WM_DELETE_WINDOW;
38 extern Atom _XA_WM_SAVE_YOURSELF;
39 extern Atom _XA_GNUSTEP_WM_ATTR;
40 extern Atom _XA_GNUSTEP_WM_MINIATURIZE_WINDOW;
41 extern Atom _XA_WINDOWMAKER_WM_FUNCTION;
42 extern Atom _XA_WINDOWMAKER_MENU;
43 extern Atom _XA_WINDOWMAKER_WM_PROTOCOLS;
44 extern Atom _XA_WINDOWMAKER_NOTICEBOARD;
45 extern Atom _XA_WINDOWMAKER_ICON_TILE;
47 int PropGetNormalHints(Window window, XSizeHints * size_hints, int *pre_iccm)
49 long supplied_hints;
51 if (!XGetWMNormalHints(dpy, window, size_hints, &supplied_hints)) {
52 return False;
54 if (supplied_hints == (USPosition | USSize | PPosition | PSize | PMinSize | PMaxSize
55 | PResizeInc | PAspect)) {
56 *pre_iccm = 1;
57 } else {
58 *pre_iccm = 0;
60 return True;
63 int PropGetWMClass(Window window, char **wm_class, char **wm_instance)
65 XClassHint *class_hint;
67 class_hint = XAllocClassHint();
68 if (XGetClassHint(dpy, window, class_hint) == 0) {
69 *wm_class = strdup("default");
70 *wm_instance = strdup("default");
71 XFree(class_hint);
72 return False;
74 *wm_instance = strdup(class_hint->res_name);
75 *wm_class = strdup(class_hint->res_class);
77 XFree(class_hint->res_name);
78 XFree(class_hint->res_class);
79 XFree(class_hint);
81 return True;
84 void PropGetProtocols(Window window, WProtocols * prots)
86 Atom *protocols;
87 int count, i;
89 memset(prots, 0, sizeof(WProtocols));
90 if (!XGetWMProtocols(dpy, window, &protocols, &count)) {
91 return;
93 for (i = 0; i < count; i++) {
94 if (protocols[i] == _XA_WM_TAKE_FOCUS)
95 prots->TAKE_FOCUS = 1;
96 else if (protocols[i] == _XA_WM_DELETE_WINDOW)
97 prots->DELETE_WINDOW = 1;
98 else if (protocols[i] == _XA_WM_SAVE_YOURSELF)
99 prots->SAVE_YOURSELF = 1;
100 else if (protocols[i] == _XA_GNUSTEP_WM_MINIATURIZE_WINDOW)
101 prots->MINIATURIZE_WINDOW = 1;
103 XFree(protocols);
106 unsigned char *PropGetCheckProperty(Window window, Atom hint, Atom type, int format, int count, int *retCount)
108 Atom type_ret;
109 int fmt_ret;
110 unsigned long nitems_ret;
111 unsigned long bytes_after_ret;
112 unsigned char *data;
113 int tmp;
115 if (count <= 0)
116 tmp = 0xffffff;
117 else
118 tmp = count;
120 if (XGetWindowProperty(dpy, window, hint, 0, tmp, False, type,
121 &type_ret, &fmt_ret, &nitems_ret, &bytes_after_ret,
122 (unsigned char **)&data) != Success || !data)
123 return NULL;
125 if ((type != AnyPropertyType && type != type_ret)
126 || (count > 0 && nitems_ret != count)
127 || (format != 0 && format != fmt_ret)) {
128 XFree(data);
129 return NULL;
132 if (retCount)
133 *retCount = nitems_ret;
135 return data;
138 int PropGetGNUstepWMAttr(Window window, GNUstepWMAttributes ** attr)
140 unsigned long *data;
142 data = (unsigned long *)PropGetCheckProperty(window, _XA_GNUSTEP_WM_ATTR,
143 _XA_GNUSTEP_WM_ATTR, 32, 9, NULL);
145 if (!data)
146 return False;
148 *attr = malloc(sizeof(GNUstepWMAttributes));
149 if (!*attr) {
150 XFree(data);
151 return False;
153 (*attr)->flags = data[0];
154 (*attr)->window_style = data[1];
155 (*attr)->window_level = data[2];
156 (*attr)->reserved = data[3];
157 (*attr)->miniaturize_pixmap = data[4];
158 (*attr)->close_pixmap = data[5];
159 (*attr)->miniaturize_mask = data[6];
160 (*attr)->close_mask = data[7];
161 (*attr)->extra_flags = data[8];
163 XFree(data);
165 return True;
168 void PropSetWMakerProtocols(Window root)
170 Atom protocols[3];
171 int count = 0;
173 protocols[count++] = _XA_WINDOWMAKER_MENU;
174 protocols[count++] = _XA_WINDOWMAKER_WM_FUNCTION;
175 protocols[count++] = _XA_WINDOWMAKER_NOTICEBOARD;
177 XChangeProperty(dpy, root, _XA_WINDOWMAKER_WM_PROTOCOLS, XA_ATOM,
178 32, PropModeReplace, (unsigned char *)protocols, count);
181 void PropSetIconTileHint(WScreen * scr, RImage * image)
183 static Atom imageAtom = 0;
184 unsigned char *tmp;
185 int x, y;
187 if (scr->info_window == None)
188 return;
190 if (!imageAtom) {
192 * WIDTH, HEIGHT (16 bits, MSB First)
193 * array of R,G,B,A bytes
195 imageAtom = XInternAtom(dpy, "_RGBA_IMAGE", False);
198 tmp = malloc(image->width * image->height * 4 + 4);
199 if (!tmp) {
200 wwarning("could not allocate memory to set _WINDOWMAKER_ICON_TILE hint");
201 return;
204 tmp[0] = image->width >> 8;
205 tmp[1] = image->width & 0xff;
206 tmp[2] = image->height >> 8;
207 tmp[3] = image->height & 0xff;
209 if (image->format == RRGBAFormat) {
210 memcpy(&tmp[4], image->data, image->width * image->height * 4);
211 } else {
212 char *ptr = (char *)(tmp + 4);
213 char *src = (char *)image->data;
215 for (y = 0; y < image->height; y++) {
216 for (x = 0; x < image->width; x++) {
217 *ptr++ = *src++;
218 *ptr++ = *src++;
219 *ptr++ = *src++;
220 *ptr++ = 255;
225 XChangeProperty(dpy, scr->info_window, _XA_WINDOWMAKER_ICON_TILE,
226 imageAtom, 8, PropModeReplace, tmp, image->width * image->height * 4 + 4);
227 wfree(tmp);
231 Window PropGetClientLeader(Window window)
233 Window *win;
234 Window leader;
236 win = (Window *) PropGetCheckProperty(window, _XA_WM_CLIENT_LEADER, XA_WINDOW, 32, 1, NULL);
238 if (!win)
239 return None;
241 leader = (Window) * win;
242 XFree(win);
244 return leader;
247 int PropGetWindowState(Window window)
249 long *data;
250 long state;
252 data = (long *)PropGetCheckProperty(window, _XA_WM_STATE, _XA_WM_STATE, 32, 1, NULL);
254 if (!data)
255 return -1;
257 state = *data;
258 XFree(data);
260 return state;
263 void PropCleanUp(Window root)
265 XDeleteProperty(dpy, root, _XA_WINDOWMAKER_WM_PROTOCOLS);
266 XDeleteProperty(dpy, root, _XA_WINDOWMAKER_NOTICEBOARD);
267 XDeleteProperty(dpy, root, XA_WM_ICON_SIZE);