1 /* $Id$
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., Inc., 51 Franklin Street, Fifth Floor, Boston,
16 MA 02110-1301, USA.
17
18
19 xfwm4 - (c) 2002-2011 Olivier Fourdan
20
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <X11/Xlib.h>
28 #include <X11/Xutil.h>
29 #include <glib.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <glib.h>
33 #include <libxfce4util/libxfce4util.h>
34 #include "mypixmap.h"
35 #include "mywindow.h"
36 #include "screen.h"
37
38 static void
xfwmWindowSetVisual(xfwmWindow * win,Visual * visual,gint depth)39 xfwmWindowSetVisual (xfwmWindow * win, Visual *visual, gint depth)
40 {
41 g_return_if_fail (win->screen_info != NULL);
42
43 if (visual)
44 {
45 win->visual = visual;
46 }
47 else
48 {
49 win->visual = win->screen_info->visual;
50 }
51
52 if (depth)
53 {
54 win->depth = depth;
55 }
56 else
57 {
58 win->depth = win->screen_info->depth;
59 }
60 }
61
62 void
xfwmWindowInit(xfwmWindow * win)63 xfwmWindowInit (xfwmWindow * win)
64 {
65 g_return_if_fail (win != NULL);
66
67 win->window = None;
68 win->map = FALSE;
69 win->screen_info = NULL;
70 win->depth = 0;
71 win->x = 0;
72 win->y = 0;
73 win->width = 1;
74 win->height = 1;
75 #ifdef HAVE_RENDER
76 win->pict_format = NULL;
77 #endif
78 }
79
80 void
xfwmWindowSetCursor(xfwmWindow * win,Cursor cursor)81 xfwmWindowSetCursor (xfwmWindow * win, Cursor cursor)
82 {
83 ScreenInfo *screen_info;
84 DisplayInfo *display_info;
85
86 g_return_if_fail (win != NULL);
87
88 screen_info = win->screen_info;
89 display_info = screen_info->display_info;
90
91 if ((win->window != None) && (cursor != None))
92 {
93 myDisplayErrorTrapPush (display_info);
94 XDefineCursor (myScreenGetXDisplay (screen_info), win->window, cursor);
95 myDisplayErrorTrapPopIgnored (display_info);
96 }
97 }
98
99 void
xfwmWindowCreate(ScreenInfo * screen_info,Visual * visual,gint depth,Window parent,xfwmWindow * win,long eventmask,Cursor cursor)100 xfwmWindowCreate (ScreenInfo * screen_info, Visual *visual, gint depth, Window parent,
101 xfwmWindow * win, long eventmask, Cursor cursor)
102 {
103 XSetWindowAttributes attributes;
104 unsigned long valuemask;
105
106 TRACE ("parent (0x%lx)", parent);
107
108 g_return_if_fail (screen_info != NULL);
109
110 attributes.event_mask = eventmask;
111 valuemask = 0L;
112 if (eventmask != NoEventMask)
113 {
114 valuemask |= CWEventMask;
115 }
116
117 win->window = XCreateWindow (myScreenGetXDisplay (screen_info),
118 parent, 0, 0, 1, 1, 0, 0,
119 InputOutput, CopyFromParent,
120 valuemask, &attributes);
121
122 TRACE ("new XID (0x%lx)", win->window);
123
124 win->map = FALSE;
125 win->screen_info = screen_info;
126 win->x = 0;
127 win->y = 0;
128 win->width = 1;
129 win->height = 1;
130 xfwmWindowSetVisual (win, visual, depth);
131 xfwmWindowSetCursor (win, cursor);
132 #ifdef HAVE_RENDER
133 win->pict_format = XRenderFindVisualFormat (myScreenGetXDisplay (screen_info), win->visual);
134 #endif
135 #ifdef HAVE_XI2
136 xfwm_device_configure_xi2_event_mask (screen_info->display_info->devices,
137 screen_info->display_info->dpy,
138 win->window, eventmask);
139 #endif
140 }
141
142 void
xfwmWindowDelete(xfwmWindow * win)143 xfwmWindowDelete (xfwmWindow * win)
144 {
145 TRACE ("win %p (0x%lx)", win, win->window);
146
147 if (win->window != None)
148 {
149 XDestroyWindow (myScreenGetXDisplay (win->screen_info),
150 win->window);
151 win->window = None;
152 }
153 win->map = FALSE;
154 }
155
156 void
xfwmWindowShow(xfwmWindow * win,int x,int y,int width,int height,gboolean refresh)157 xfwmWindowShow (xfwmWindow * win, int x, int y, int width, int height,
158 gboolean refresh)
159 {
160 ScreenInfo *screen_info;
161 DisplayInfo *display_info;
162
163 TRACE ("win %p (0x%lx) at (%i,%i) [%i×%i]", win, win->window, x, y, width, height);
164
165 if (!(win->window))
166 {
167 return;
168 }
169 if ((width < 1) || (height < 1))
170 {
171 xfwmWindowHide (win);
172 return;
173 }
174
175 screen_info = win->screen_info;
176 display_info = screen_info->display_info;
177 myDisplayErrorTrapPush (display_info);
178
179 if (!(win->map))
180 {
181 XMapWindow (myScreenGetXDisplay (screen_info),
182 win->window);
183 win->map = TRUE;
184 }
185
186 if (((x != win->x) || (y != win->y)) && ((width != win->width)
187 || (height != win->height)))
188 {
189 XMoveResizeWindow (myScreenGetXDisplay (screen_info),
190 win->window, x, y,
191 (unsigned int) width,
192 (unsigned int) height);
193 win->x = x;
194 win->y = y;
195 win->width = width;
196 win->height = height;
197 }
198 else if ((x != win->x) || (y != win->y))
199 {
200 XMoveWindow (myScreenGetXDisplay (screen_info),
201 win->window,
202 x, y);
203 if (refresh)
204 {
205 XClearWindow (myScreenGetXDisplay (screen_info),
206 win->window);
207 }
208 win->x = x;
209 win->y = y;
210 }
211 else if ((width != win->width) || (height != win->height))
212 {
213 XResizeWindow (myScreenGetXDisplay (screen_info),
214 win->window,
215 (unsigned int) width,
216 (unsigned int) height);
217 win->width = width;
218 win->height = height;
219 }
220 else if (refresh)
221 {
222 XClearWindow (myScreenGetXDisplay (screen_info),
223 win->window);
224 }
225 myDisplayErrorTrapPopIgnored (display_info);
226 }
227
228 void
xfwmWindowHide(xfwmWindow * win)229 xfwmWindowHide (xfwmWindow * win)
230 {
231 TRACE ("win %p (0x%lx)", win, win->window);
232
233 if (win->map)
234 {
235 g_assert (win->window);
236 XUnmapWindow (myScreenGetXDisplay (win->screen_info), win->window);
237 win->map = FALSE;
238 }
239 }
240
241 gboolean
xfwmWindowVisible(xfwmWindow * win)242 xfwmWindowVisible (xfwmWindow *win)
243 {
244 g_return_val_if_fail (win, FALSE);
245
246 return win->map;
247 }
248
249 gboolean
xfwmWindowDeleted(xfwmWindow * win)250 xfwmWindowDeleted (xfwmWindow *win)
251 {
252 g_return_val_if_fail (win, TRUE);
253
254 return (win->window == None);
255 }
256
257 void
xfwmWindowTemp(ScreenInfo * screen_info,Visual * visual,gint depth,Window parent,xfwmWindow * win,int x,int y,int width,int height,long eventmask,gboolean bottom)258 xfwmWindowTemp (ScreenInfo *screen_info, Visual *visual,
259 gint depth, Window parent,
260 xfwmWindow * win,
261 int x, int y, int width, int height,
262 long eventmask,
263 gboolean bottom)
264 {
265 XSetWindowAttributes attributes;
266 DisplayInfo *display_info;
267
268 display_info = screen_info->display_info;
269 myDisplayErrorTrapPush (display_info);
270
271 attributes.event_mask = eventmask;
272 attributes.override_redirect = TRUE;
273 win->window = XCreateWindow (myScreenGetXDisplay (screen_info),
274 parent, x, y, width, height, 0, 0,
275 InputOnly, CopyFromParent,
276 CWEventMask | CWOverrideRedirect,
277 &attributes);
278 if (bottom)
279 {
280 XLowerWindow (myScreenGetXDisplay (screen_info), win->window);
281 }
282 else
283 {
284 XRaiseWindow (myScreenGetXDisplay (screen_info), win->window);
285 }
286
287 XMapWindow (myScreenGetXDisplay (screen_info), win->window);
288 win->map = TRUE;
289 win->screen_info = screen_info;
290 win->x = x;
291 win->y = y;
292 win->width = width;
293 win->height = height;
294 xfwmWindowSetVisual (win, visual, depth);
295 #ifdef HAVE_XI2
296 xfwm_device_configure_xi2_event_mask (screen_info->display_info->devices,
297 screen_info->display_info->dpy,
298 win->window, eventmask);
299 #endif
300 myDisplayErrorTrapPopIgnored (display_info);
301 }
302
303 #ifdef HAVE_RENDER
304 static gboolean
xfwmWindowCopyComposite(xfwmWindow * win,xfwmPixmap * pix)305 xfwmWindowCopyComposite (xfwmWindow * win, xfwmPixmap * pix)
306 {
307 if (myDisplayHaveRender (win->screen_info->display_info))
308 {
309 Picture pict;
310 Pixmap temp;
311
312 if (!pix->pict)
313 {
314 TRACE ("pixmap picture does not exist");
315 return FALSE;
316 }
317
318 if (!win->pict_format)
319 {
320 TRACE ("window picture format is unknown");
321 return FALSE;
322 }
323
324 temp = XCreatePixmap (myScreenGetXDisplay (win->screen_info),
325 win->window,
326 pix->width, pix->height, win->depth);
327
328 if (!temp)
329 {
330 return FALSE;
331 }
332
333 pict = XRenderCreatePicture (myScreenGetXDisplay (win->screen_info),
334 temp, win->pict_format, 0, NULL);
335
336 if (!pict)
337 {
338 XFreePixmap (myScreenGetXDisplay (win->screen_info), temp);
339 return FALSE;
340 }
341
342 XRenderComposite (myScreenGetXDisplay (win->screen_info), PictOpSrc, pix->pict, None, pict, 0, 0, 0, 0, 0, 0, pix->width, pix->height);
343
344 XRenderFreePicture (myScreenGetXDisplay (win->screen_info), pict);
345
346 XSetWindowBackgroundPixmap (myScreenGetXDisplay (win->screen_info), win->window, temp);
347
348 XFreePixmap (myScreenGetXDisplay (win->screen_info), temp);
349 return TRUE;
350 }
351 return FALSE;
352 }
353 #endif
354
355 void
xfwmWindowSetBG(xfwmWindow * win,xfwmPixmap * pix)356 xfwmWindowSetBG (xfwmWindow * win, xfwmPixmap * pix)
357 {
358 ScreenInfo *screen_info;
359 DisplayInfo *display_info;
360 gboolean done;
361
362 if ((win->width < 1) || (win->height < 1) || (pix->width < 1) || (pix->height < 1))
363 {
364 return;
365 }
366
367 screen_info = win->screen_info;
368 display_info = screen_info->display_info;
369 myDisplayErrorTrapPush (display_info);
370
371 done = FALSE;
372 #ifdef HAVE_RENDER
373 if ((win->visual != screen_info->visual) ||
374 (win->depth != screen_info->depth))
375 {
376 /* Try to use Render */
377 done = xfwmWindowCopyComposite (win, pix);
378 }
379 #endif
380
381 if (!done)
382 {
383 /* Use the good old way */
384 XSetWindowBackgroundPixmap (myScreenGetXDisplay (screen_info), win->window, pix->pixmap);
385 }
386
387 myDisplayErrorTrapPopIgnored (display_info);
388 }
389