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