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