Change to the linux kernel coding style
[wmaker-crm.git] / src / properties.c
Commit [+]AuthorDateLineData
9d2e6ef9 scottc1998-09-29 22:36:29 +00001/*
9af1c6c4 dan1998-10-21 14:43:47 +00002 * Window Maker window manager
6830b057 dan2004-10-12 21:28:27 +00003 *
4153e2fd dan2003-01-16 23:30:45 +00004 * Copyright (c) 1997-2003 Alfredo K. Kojima
6830b057 dan2004-10-12 21:28:27 +00005 *
9d2e6ef9 scottc1998-09-29 22:36:29 +00006 * 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.
10 *
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.
15 *
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
6830b057 dan2004-10-12 21:28:27 +000018 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
9d2e6ef9 scottc1998-09-29 22:36:29 +000019 * USA.
20 */
21
22#include "wconfig.h"
23
24#include <X11/Xlib.h>
25#include <X11/Xutil.h>
26#include <X11/Xatom.h>
27#include <string.h>
28#include <stdlib.h>
29
30#include "WindowMaker.h"
31#include "window.h"
32#include "GNUstep.h"
9d2e6ef9 scottc1998-09-29 22:36:29 +000033
9d2e6ef9 scottc1998-09-29 22:36:29 +000034/* atoms */
35extern Atom _XA_WM_STATE;
36extern Atom _XA_WM_CHANGE_STATE;
37extern Atom _XA_WM_PROTOCOLS;
38extern Atom _XA_WM_CLIENT_LEADER;
39extern Atom _XA_WM_TAKE_FOCUS;
40extern Atom _XA_WM_DELETE_WINDOW;
41extern Atom _XA_WM_SAVE_YOURSELF;
416e3a82 dan1999-01-25 19:06:50 +000042#ifdef XSMP_ENABLED
9007a657 dan1998-11-23 11:32:19 +000043extern Atom _XA_WM_WINDOW_ROLE;
44extern Atom _XA_SM_CLIENT_ID;
45#endif
46
9d2e6ef9 scottc1998-09-29 22:36:29 +000047extern Atom _XA_GNUSTEP_WM_ATTR;
9af1c6c4 dan1998-10-21 14:43:47 +000048extern Atom _XA_GNUSTEP_WM_MINIATURIZE_WINDOW;
9d2e6ef9 scottc1998-09-29 22:36:29 +000049
50extern Atom _XA_WINDOWMAKER_WM_FUNCTION;
51extern Atom _XA_WINDOWMAKER_MENU;
52extern Atom _XA_WINDOWMAKER_WM_PROTOCOLS;
416e3a82 dan1999-01-25 19:06:50 +000053extern Atom _XA_WINDOWMAKER_NOTICEBOARD;
754230a6 kojima2000-02-16 18:26:15 +000054extern Atom _XA_WINDOWMAKER_ICON_TILE;
55extern Atom _XA_WINDOWMAKER_ICON_SIZE;
9d2e6ef9 scottc1998-09-29 22:36:29 +000056
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020057int PropGetNormalHints(Window window, XSizeHints * size_hints, int *pre_iccm)
9d2e6ef9 scottc1998-09-29 22:36:29 +000058{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020059 long supplied_hints;
60
61 if (!XGetWMNormalHints(dpy, window, size_hints, &supplied_hints)) {
62 return False;
63 }
64 if (supplied_hints == (USPosition | USSize | PPosition | PSize | PMinSize | PMaxSize
65 | PResizeInc | PAspect)) {
66 *pre_iccm = 1;
67 } else {
68 *pre_iccm = 0;
69 }
70 return True;
9d2e6ef9 scottc1998-09-29 22:36:29 +000071}
72
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020073int PropGetWMClass(Window window, char **wm_class, char **wm_instance)
9d2e6ef9 scottc1998-09-29 22:36:29 +000074{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020075 XClassHint *class_hint;
76
77 class_hint = XAllocClassHint();
78 if (XGetClassHint(dpy, window, class_hint) == 0) {
79 *wm_class = NULL;
80 *wm_instance = NULL;
81 XFree(class_hint);
82 return False;
83 }
84 *wm_instance = class_hint->res_name;
85 *wm_class = class_hint->res_class;
86
87 XFree(class_hint);
88 return True;
9d2e6ef9 scottc1998-09-29 22:36:29 +000089}
90
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020091void PropGetProtocols(Window window, WProtocols * prots)
9d2e6ef9 scottc1998-09-29 22:36:29 +000092{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020093 Atom *protocols;
94 int count, i;
95
96 memset(prots, 0, sizeof(WProtocols));
97 if (!XGetWMProtocols(dpy, window, &protocols, &count)) {
98 return;
99 }
100 for (i = 0; i < count; i++) {
101 if (protocols[i] == _XA_WM_TAKE_FOCUS)
102 prots->TAKE_FOCUS = 1;
103 else if (protocols[i] == _XA_WM_DELETE_WINDOW)
104 prots->DELETE_WINDOW = 1;
105 else if (protocols[i] == _XA_WM_SAVE_YOURSELF)
106 prots->SAVE_YOURSELF = 1;
107 else if (protocols[i] == _XA_GNUSTEP_WM_MINIATURIZE_WINDOW)
108 prots->MINIATURIZE_WINDOW = 1;
109 }
110 XFree(protocols);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000111}
112
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200113unsigned char *PropGetCheckProperty(Window window, Atom hint, Atom type, int format, int count, int *retCount)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000114{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200115 Atom type_ret;
116 int fmt_ret;
117 unsigned long nitems_ret;
118 unsigned long bytes_after_ret;
119 unsigned char *data;
120 int tmp;
121
122 if (count <= 0)
123 tmp = 0xffffff;
124 else
125 tmp = count;
126
127 if (XGetWindowProperty(dpy, window, hint, 0, tmp, False, type,
128 &type_ret, &fmt_ret, &nitems_ret, &bytes_after_ret,
129 (unsigned char **)&data) != Success || !data)
130 return NULL;
131
132 if ((type != AnyPropertyType && type != type_ret)
133 || (count > 0 && nitems_ret != count)
134 || (format != 0 && format != fmt_ret)) {
135 XFree(data);
136 return NULL;
137 }
138
139 if (retCount)
140 *retCount = nitems_ret;
141
142 return data;
0261c326 dan1999-01-06 15:22:33 +0000143}
144
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200145int PropGetGNUstepWMAttr(Window window, GNUstepWMAttributes ** attr)
0261c326 dan1999-01-06 15:22:33 +0000146{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200147 unsigned long *data;
148
149 data = (unsigned long *)PropGetCheckProperty(window, _XA_GNUSTEP_WM_ATTR,
150 _XA_GNUSTEP_WM_ATTR, 32, 9, NULL);
151
152 if (!data)
153 return False;
154
155 *attr = malloc(sizeof(GNUstepWMAttributes));
156 if (!*attr) {
157 XFree(data);
158 return False;
159 }
160 (*attr)->flags = data[0];
161 (*attr)->window_style = data[1];
162 (*attr)->window_level = data[2];
163 (*attr)->reserved = data[3];
164 (*attr)->miniaturize_pixmap = data[4];
165 (*attr)->close_pixmap = data[5];
166 (*attr)->miniaturize_mask = data[6];
167 (*attr)->close_mask = data[7];
168 (*attr)->extra_flags = data[8];
169
170 XFree(data);
171
172 return True;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000173}
174
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200175void PropSetWMakerProtocols(Window root)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000176{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200177 Atom protocols[3];
178 int count = 0;
6830b057 dan2004-10-12 21:28:27 +0000179
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200180 protocols[count++] = _XA_WINDOWMAKER_MENU;
181 protocols[count++] = _XA_WINDOWMAKER_WM_FUNCTION;
182 protocols[count++] = _XA_WINDOWMAKER_NOTICEBOARD;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000183
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200184 XChangeProperty(dpy, root, _XA_WINDOWMAKER_WM_PROTOCOLS, XA_ATOM,
185 32, PropModeReplace, (unsigned char *)protocols, count);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000186}
187
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200188void PropSetIconTileHint(WScreen * scr, RImage * image)
754230a6 kojima2000-02-16 18:26:15 +0000189{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200190 static Atom imageAtom = 0;
191 unsigned char *tmp;
192 int x, y;
193
194 if (scr->info_window == None)
195 return;
196
197 if (!imageAtom) {
198 /*
199 * WIDTH, HEIGHT (16 bits, MSB First)
200 * array of R,G,B,A bytes
201 */
202 imageAtom = XInternAtom(dpy, "_RGBA_IMAGE", False);
203 }
204
205 tmp = malloc(image->width * image->height * 4 + 4);
206 if (!tmp) {
207 wwarning("could not allocate memory to set _WINDOWMAKER_ICON_TILE hint");
208 return;
209 }
210
211 tmp[0] = image->width >> 8;
212 tmp[1] = image->width & 0xff;
213 tmp[2] = image->height >> 8;
214 tmp[3] = image->height & 0xff;
215
216 if (image->format == RRGBAFormat) {
217 memcpy(&tmp[4], image->data, image->width * image->height * 4);
218 } else {
219 char *ptr = (char *)(tmp + 4);
220 char *src = (char *)image->data;
221
222 for (y = 0; y < image->height; y++) {
223 for (x = 0; x < image->width; x++) {
224 *ptr++ = *src++;
225 *ptr++ = *src++;
226 *ptr++ = *src++;
227 *ptr++ = 255;
228 }
229 }
230 }
231
232 XChangeProperty(dpy, scr->info_window, _XA_WINDOWMAKER_ICON_TILE,
233 imageAtom, 8, PropModeReplace, tmp, image->width * image->height * 4 + 4);
234 wfree(tmp);
6830b057 dan2004-10-12 21:28:27 +0000235
754230a6 kojima2000-02-16 18:26:15 +0000236}
237
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200238Window PropGetClientLeader(Window window)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000239{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200240 Window *win;
241 Window leader;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000242
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200243 win = (Window *) PropGetCheckProperty(window, _XA_WM_CLIENT_LEADER, XA_WINDOW, 32, 1, NULL);
0261c326 dan1999-01-06 15:22:33 +0000244
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200245 if (!win)
246 return None;
9d2e6ef9 scottc1998-09-29 22:36:29 +0000247
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200248 leader = (Window) * win;
249 XFree(win);
9007a657 dan1998-11-23 11:32:19 +0000250
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200251 return leader;
9007a657 dan1998-11-23 11:32:19 +0000252}
253
416e3a82 dan1999-01-25 19:06:50 +0000254#ifdef XSMP_ENABLED
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200255char *PropGetClientID(Window window)
9007a657 dan1998-11-23 11:32:19 +0000256{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200257 XTextProperty txprop;
6830b057 dan2004-10-12 21:28:27 +0000258
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200259 txprop.value = NULL;
9007a657 dan1998-11-23 11:32:19 +0000260
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200261 if (XGetTextProperty(dpy, window, &txprop, _XA_SM_CLIENT_ID) != Success) {
262 return NULL;
263 }
9007a657 dan1998-11-23 11:32:19 +0000264
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200265 if (txprop.encoding == XA_STRING && txprop.format == 8 && txprop.nitems > 0) {
6830b057 dan2004-10-12 21:28:27 +0000266
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200267 return (char *)txprop.value;
268 } else {
9007a657 dan1998-11-23 11:32:19 +0000269
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200270 if (txprop.value)
271 XFree(txprop.value);
9007a657 dan1998-11-23 11:32:19 +0000272
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200273 return NULL;
274 }
9d2e6ef9 scottc1998-09-29 22:36:29 +0000275}
276
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200277char *PropGetWindowRole(Window window)
9007a657 dan1998-11-23 11:32:19 +0000278{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200279 XTextProperty txprop;
6830b057 dan2004-10-12 21:28:27 +0000280
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200281 txprop.value = NULL;
9007a657 dan1998-11-23 11:32:19 +0000282
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200283 if (XGetTextProperty(dpy, window, &txprop, _XA_WM_WINDOW_ROLE) != Success) {
284 return NULL;
285 }
9007a657 dan1998-11-23 11:32:19 +0000286
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200287 if (txprop.encoding == XA_STRING && txprop.format == 8 && txprop.nitems > 0) {
9007a657 dan1998-11-23 11:32:19 +0000288
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200289 return (char *)txprop.value;
290 } else {
9007a657 dan1998-11-23 11:32:19 +0000291
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200292 if (txprop.value)
293 XFree(txprop.value);
9007a657 dan1998-11-23 11:32:19 +0000294
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200295 return NULL;
296 }
9007a657 dan1998-11-23 11:32:19 +0000297}
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200298#endif /* XSMP_ENABLED */
9d2e6ef9 scottc1998-09-29 22:36:29 +0000299
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200300void PropWriteGNUstepWMAttr(Window window, GNUstepWMAttributes * attr)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000301{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200302 unsigned long data[9];
303
304 data[0] = attr->flags;
305 data[1] = attr->window_style;
306 data[2] = attr->window_level;
307 data[3] = 0; /* reserved */
308 /* The X protocol says XIDs are 32bit */
309 data[4] = attr->miniaturize_pixmap;
310 data[5] = attr->close_pixmap;
311 data[6] = attr->miniaturize_mask;
312 data[7] = attr->close_mask;
313 data[8] = attr->extra_flags;
314 XChangeProperty(dpy, window, _XA_GNUSTEP_WM_ATTR, _XA_GNUSTEP_WM_ATTR,
315 32, PropModeReplace, (unsigned char *)data, 9);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000316}
317
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200318int PropGetWindowState(Window window)
088c0ac2 dan1999-03-09 14:58:01 +0000319{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200320 long *data;
321 long state;
088c0ac2 dan1999-03-09 14:58:01 +0000322
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200323 data = (long *)PropGetCheckProperty(window, _XA_WM_STATE, _XA_WM_STATE, 32, 1, NULL);
088c0ac2 dan1999-03-09 14:58:01 +0000324
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200325 if (!data)
326 return -1;
088c0ac2 dan1999-03-09 14:58:01 +0000327
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200328 state = *data;
329 XFree(data);
088c0ac2 dan1999-03-09 14:58:01 +0000330
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200331 return state;
088c0ac2 dan1999-03-09 14:58:01 +0000332}
333
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200334void PropCleanUp(Window root)
9d2e6ef9 scottc1998-09-29 22:36:29 +0000335{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200336 XDeleteProperty(dpy, root, _XA_WINDOWMAKER_WM_PROTOCOLS);
416e3a82 dan1999-01-25 19:06:50 +0000337
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200338 XDeleteProperty(dpy, root, _XA_WINDOWMAKER_NOTICEBOARD);
416e3a82 dan1999-01-25 19:06:50 +0000339
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200340 XDeleteProperty(dpy, root, XA_WM_ICON_SIZE);
9d2e6ef9 scottc1998-09-29 22:36:29 +0000341}