1 /*
2 * Copyright © 2008 Dennis Kasprzyk <onestone@opencompositing.org>
3 * Copyright © 2006 Novell, Inc.
4 * Copyright © 2006 Volker Krause <vkrause@kde.org>
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.
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
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 *
21 * Author: David Reveman <davidr@novell.com>
22 */
23
24 #include "utils.h"
25
26 #include <decoration.h>
27 #include <X11/Xlib.h>
28 #include <X11/Xatom.h>
29
30 #include <stdlib.h>
31 #include <QX11Info>
32
33 static int trappedErrorCode = 0;
34
35 namespace KWD
36 {
37 namespace Atoms
38 {
39 Atom switchSelectWindow;
40 Atom switchFgColor;
41 Atom netWmWindowOpacity;
42 Atom netFrameWindow;
43 Atom netWindowDecor;
44 Atom netWindowDecorNormal;
45 Atom netWindowDecorActive;
46 Atom netWindowDecorBare;
47 Atom wmTakeFocus;
48 Atom netWmContextHelp;
49 Atom wmProtocols;
50 Atom toolkitActionAtom;
51 Atom toolkitActionWindowMenuAtom;
52 Atom toolkitActionForceQuitDialogAtom;
53 Atom compizWindowBlurDecor;
54 Atom enlightmentDesktop;
55 }
56 }
57
58 static int (*oldErrorHandler) (Display *display, XErrorEvent *error);
59
60 static int
xErrorHandler(Display * display,XErrorEvent * error)61 xErrorHandler (Display *display,
62 XErrorEvent *error)
63 {
64 (void) display;
65
66 trappedErrorCode = error->error_code;
67
68 return 0;
69 }
70
71 void
trapXError(void)72 KWD::trapXError (void)
73 {
74 trappedErrorCode = 0;
75 oldErrorHandler = XSetErrorHandler (xErrorHandler);
76 }
77
78 int
popXError(void)79 KWD::popXError (void)
80 {
81 XSync (QX11Info::display(), false);
82 XSetErrorHandler (oldErrorHandler);
83
84 return trappedErrorCode;
85 }
86
87 void *
readXProperty(WId window,Atom property,Atom type,int * items)88 KWD::readXProperty (WId window,
89 Atom property,
90 Atom type,
91 int *items)
92 {
93 long offset = 0, length = 2048L;
94 Atom actualType;
95 int format;
96 unsigned long nItems, bytesRemaining;
97 unsigned char *data = 0l;
98 int result;
99
100 KWD::trapXError ();
101 result = XGetWindowProperty (QX11Info::display(), window, property, offset,
102 length, false, type,
103 &actualType, &format, &nItems,
104 &bytesRemaining, &data);
105
106 if (KWD::popXError ())
107 return NULL;
108
109 if (result == Success && actualType == type && format == 32 && nItems > 0)
110 {
111 if (items)
112 *items = nItems;
113
114 return reinterpret_cast <void *>(data);
115 }
116
117 if (data)
118 XFree (data);
119
120 if (items)
121 *items = 0;
122
123 return NULL;
124 }
125
126 bool
readWindowProperty(long window,long property,long * value)127 KWD::readWindowProperty (long window,
128 long property,
129 long *value)
130 {
131 void *data = readXProperty (window, property, XA_WINDOW, NULL);
132
133 if (data)
134 {
135 if (value)
136 *value = *reinterpret_cast <int *>(data);
137
138 XFree (data);
139
140 return true;
141 }
142
143 return false;
144 }
145
146 unsigned short
readPropertyShort(WId id,Atom property,unsigned short defaultValue)147 KWD::readPropertyShort (WId id,
148 Atom property,
149 unsigned short defaultValue)
150 {
151 Atom actual;
152 int result, format;
153 unsigned long n, left;
154 unsigned char *data;
155
156 KWD::trapXError ();
157 result = XGetWindowProperty (QX11Info::display(), id, property,
158 0L, 1L, FALSE, XA_CARDINAL, &actual, &format,
159 &n, &left, &data);
160 if (KWD::popXError ())
161 return defaultValue;
162
163 if (result == Success && n && data)
164 {
165 unsigned int value;
166
167 memcpy (&value, data, sizeof (unsigned int));
168
169 XFree (data);
170
171 return value >> 16;
172 }
173
174 return defaultValue;
175 }
176
177 void
init(void)178 KWD::Atoms::init (void)
179 {
180 Display *xdisplay = QX11Info::display();
181
182 netFrameWindow = XInternAtom (xdisplay, "_NET_FRAME_WINDOW", false);
183 netWindowDecor = XInternAtom (xdisplay, DECOR_WINDOW_ATOM_NAME, false);
184 netWindowDecorNormal =
185 XInternAtom (xdisplay, DECOR_NORMAL_ATOM_NAME, false);
186 netWindowDecorActive =
187 XInternAtom (xdisplay, DECOR_ACTIVE_ATOM_NAME, false);
188 netWindowDecorBare =
189 XInternAtom (xdisplay, DECOR_BARE_ATOM_NAME, false);
190 switchSelectWindow =
191 XInternAtom (xdisplay, DECOR_SWITCH_WINDOW_ATOM_NAME, false);
192 switchFgColor =
193 XInternAtom (xdisplay, DECOR_SWITCH_FOREGROUND_COLOR_ATOM_NAME, false);
194 wmTakeFocus = XInternAtom (xdisplay, "WM_TAKE_FOCUS", false);
195 netWmContextHelp =
196 XInternAtom (xdisplay, "_NET_WM_CONTEXT_HELP", false);
197 wmProtocols = XInternAtom (xdisplay, "WM_PROTOCOLS", false);
198 netWmWindowOpacity =
199 XInternAtom (xdisplay, "_NET_WM_WINDOW_OPACITY", false);
200 toolkitActionAtom = XInternAtom (xdisplay, "_COMPIZ_TOOLKIT_ACTION", false);
201 toolkitActionWindowMenuAtom =
202 XInternAtom (xdisplay, "_COMPIZ_TOOLKIT_ACTION_WINDOW_MENU", false);
203 toolkitActionForceQuitDialogAtom =
204 XInternAtom (xdisplay, "_COMPIZ_TOOLKIT_ACTION_FORCE_QUIT_DIALOG",
205 false);
206 compizWindowBlurDecor =
207 XInternAtom (xdisplay, DECOR_BLUR_ATOM_NAME, false);
208 enlightmentDesktop = XInternAtom (xdisplay, "ENLIGHTENMENT_DESKTOP", false);
209 }
210