aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_window.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_window.c')
-rw-r--r--libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_window.c2233
1 files changed, 2233 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_window.c b/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_window.c
new file mode 100644
index 0000000..2616c93
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_x/xcb/ecore_xcb_window.c
@@ -0,0 +1,2233 @@
1#include "ecore_xcb_private.h"
2#ifdef ECORE_XCB_RENDER
3# include <xcb/render.h>
4#endif
5#ifdef ECORE_XCB_SHAPE
6# include <xcb/shape.h>
7#endif
8#ifdef ECORE_XCB_XPRINT
9#include <xcb/xprint.h>
10#endif
11
12/* local function prototypes */
13static Ecore_X_Window _ecore_xcb_window_argb_internal_new(Ecore_X_Window parent,
14 int x,
15 int y,
16 int w,
17 int h,
18 uint8_t override_redirect,
19 uint8_t save_under);
20static Ecore_X_Window _ecore_xcb_window_at_xy_get(Ecore_X_Window base,
21 int bx,
22 int by,
23 int x,
24 int y,
25 Ecore_X_Window *skip,
26 int skip_num);
27static int _ecore_xcb_window_modifiers_get(unsigned int state);
28static xcb_visualtype_t *_ecore_xcb_window_find_visual_by_id(xcb_visualid_t id);
29#ifdef ECORE_XCB_XPRINT
30static xcb_screen_t *_ecore_xcb_window_screen_of_display(int screen);
31#endif
32
33/* local variables */
34static int ignore_num = 0;
35static Ecore_X_Window *ignore_list = NULL;
36
37/* external variables */
38int _ecore_xcb_button_grabs_num = 0;
39int _ecore_xcb_key_grabs_num = 0;
40Ecore_X_Window *_ecore_xcb_button_grabs = NULL;
41Ecore_X_Window *_ecore_xcb_key_grabs = NULL;
42Eina_Bool (*_ecore_xcb_window_grab_replay_func)(void *data,
43 int type,
44 void *event);
45void *_ecore_xcb_window_grab_replay_data;
46
47/**
48 * @defgroup Ecore_X_Window_Create_Group X Window Creation Functions
49 *
50 * Functions that can be used to create an X window.
51 */
52
53/**
54 * Creates a new window.
55 * @param parent The parent window to use. If @p parent is @c 0, the root
56 * window of the default display is used.
57 * @param x X position.
58 * @param y Y position.
59 * @param w Width.
60 * @param h Height.
61 * @return The new window handle.
62 * @ingroup Ecore_X_Window_Create_Group
63 */
64EAPI Ecore_X_Window
65ecore_x_window_new(Ecore_X_Window parent,
66 int x,
67 int y,
68 int w,
69 int h)
70{
71 Ecore_X_Window win;
72 uint32_t mask, mask_list[9];
73
74 LOGFN(__FILE__, __LINE__, __FUNCTION__);
75 CHECK_XCB_CONN;
76
77 if (parent == 0)
78 parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
79
80 /* NB: Order here is very important due to xcb_cw_t enum */
81 mask = (XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
82 XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE |
83 XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK |
84 XCB_CW_DONT_PROPAGATE);
85
86 mask_list[0] = XCB_BACK_PIXMAP_NONE;
87 mask_list[1] = 0;
88 mask_list[2] = XCB_GRAVITY_NORTH_WEST;
89 mask_list[3] = XCB_GRAVITY_NORTH_WEST;
90 mask_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
91 mask_list[5] = 0;
92 mask_list[6] = 0;
93 mask_list[7] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
94 XCB_EVENT_MASK_BUTTON_PRESS |
95 XCB_EVENT_MASK_BUTTON_RELEASE |
96 XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
97 XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
98 XCB_EVENT_MASK_VISIBILITY_CHANGE |
99 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
100 XCB_EVENT_MASK_FOCUS_CHANGE |
101 XCB_EVENT_MASK_PROPERTY_CHANGE |
102 XCB_EVENT_MASK_COLOR_MAP_CHANGE);
103 mask_list[8] = XCB_EVENT_MASK_NO_EVENT;
104
105 win = xcb_generate_id(_ecore_xcb_conn);
106 xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT,
107 win, parent, x, y, w, h, 0,
108 XCB_WINDOW_CLASS_INPUT_OUTPUT,
109 XCB_COPY_FROM_PARENT, mask, mask_list);
110
111 if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root)
112 ecore_x_window_defaults_set(win);
113
114 return win;
115}
116
117/**
118 * Creates a window with the override redirect attribute set to @c True.
119 * @param parent The parent window to use. If @p parent is @c 0, the root
120 * window of the default display is used.
121 * @param x X position.
122 * @param y Y position.
123 * @param w Width.
124 * @param h Height.
125 * @return The new window handle.
126 * @ingroup Ecore_X_Window_Create_Group
127 */
128EAPI Ecore_X_Window
129ecore_x_window_override_new(Ecore_X_Window parent,
130 int x,
131 int y,
132 int w,
133 int h)
134{
135 Ecore_X_Window win;
136 uint32_t mask, mask_list[9];
137
138 LOGFN(__FILE__, __LINE__, __FUNCTION__);
139 CHECK_XCB_CONN;
140
141 if (parent == 0)
142 parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
143
144 /* NB: Order here is very important due to xcb_cw_t enum */
145 mask = (XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
146 XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE |
147 XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER | XCB_CW_EVENT_MASK |
148 XCB_CW_DONT_PROPAGATE);
149
150 mask_list[0] = XCB_BACK_PIXMAP_NONE;
151 mask_list[1] = 0;
152 mask_list[2] = XCB_GRAVITY_NORTH_WEST;
153 mask_list[3] = XCB_GRAVITY_NORTH_WEST;
154 mask_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
155 mask_list[5] = 1;
156 mask_list[6] = 0;
157 mask_list[7] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
158 XCB_EVENT_MASK_BUTTON_PRESS |
159 XCB_EVENT_MASK_BUTTON_RELEASE |
160 XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
161 XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
162 XCB_EVENT_MASK_VISIBILITY_CHANGE |
163 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
164 XCB_EVENT_MASK_FOCUS_CHANGE |
165 XCB_EVENT_MASK_PROPERTY_CHANGE |
166 XCB_EVENT_MASK_COLOR_MAP_CHANGE);
167 mask_list[8] = XCB_EVENT_MASK_NO_EVENT;
168
169 win = xcb_generate_id(_ecore_xcb_conn);
170 xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT,
171 win, parent, x, y, w, h, 0,
172 XCB_WINDOW_CLASS_INPUT_OUTPUT,
173 XCB_COPY_FROM_PARENT, mask, mask_list);
174
175 return win;
176}
177
178/**
179 * Creates a new input window.
180 * @param parent The parent window to use. If @p parent is @c 0, the root
181 * window of the default display is used.
182 * @param x X position.
183 * @param y Y position.
184 * @param w Width.
185 * @param h Height.
186 * @return The new window.
187 * @ingroup Ecore_X_Window_Create_Group
188 */
189EAPI Ecore_X_Window
190ecore_x_window_input_new(Ecore_X_Window parent,
191 int x,
192 int y,
193 int w,
194 int h)
195{
196 Ecore_X_Window win;
197 uint32_t mask, mask_list[3];
198
199 LOGFN(__FILE__, __LINE__, __FUNCTION__)
200 CHECK_XCB_CONN;
201
202 if (parent == 0)
203 parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
204
205 /* NB: Order here is very important due to xcb_cw_t enum */
206 mask = (XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK |
207 XCB_CW_DONT_PROPAGATE);
208
209 mask_list[0] = 1;
210 mask_list[1] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
211 XCB_EVENT_MASK_BUTTON_PRESS |
212 XCB_EVENT_MASK_BUTTON_RELEASE |
213 XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
214 XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
215 XCB_EVENT_MASK_VISIBILITY_CHANGE |
216 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
217 XCB_EVENT_MASK_FOCUS_CHANGE |
218 XCB_EVENT_MASK_PROPERTY_CHANGE |
219 XCB_EVENT_MASK_COLOR_MAP_CHANGE);
220 mask_list[2] = XCB_EVENT_MASK_NO_EVENT;
221
222 win = xcb_generate_id(_ecore_xcb_conn);
223 xcb_create_window(_ecore_xcb_conn, XCB_COPY_FROM_PARENT,
224 win, parent, x, y, w, h, 0,
225 XCB_WINDOW_CLASS_INPUT_ONLY,
226 XCB_COPY_FROM_PARENT, mask, mask_list);
227
228 return win;
229}
230
231/**
232 * Creates a new window.
233 * @param parent The parent window to use. If @p parent is @c 0, the root
234 * window of the default display is used.
235 * @param x X position.
236 * @param y Y position.
237 * @param w Width.
238 * @param h Height.
239 * @return The new window handle.
240 * @ingroup Ecore_X_Window_Create_Group
241 */
242EAPI Ecore_X_Window
243ecore_x_window_manager_argb_new(Ecore_X_Window parent,
244 int x,
245 int y,
246 int w,
247 int h)
248{
249 Ecore_X_Window win = 0;
250
251 LOGFN(__FILE__, __LINE__, __FUNCTION__);
252
253 win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 1, 0);
254
255 return win;
256}
257
258/**
259 * Creates a new window.
260 * @param parent The parent window to use. If @p parent is @c 0, the root
261 * window of the default display is used.
262 * @param x X position.
263 * @param y Y position.
264 * @param w Width.
265 * @param h Height.
266 * @return The new window handle.
267 * @ingroup Ecore_X_Window_Create_Group
268 */
269EAPI Ecore_X_Window
270ecore_x_window_argb_new(Ecore_X_Window parent,
271 int x,
272 int y,
273 int w,
274 int h)
275{
276 Ecore_X_Window win = 0;
277
278 LOGFN(__FILE__, __LINE__, __FUNCTION__);
279
280 win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 0, 0);
281
282 return win;
283}
284
285/**
286 * Creates a window with the override redirect attribute set to @c True.
287 * @param parent The parent window to use. If @p parent is @c 0, the root
288 * window of the default display is used.
289 * @param x X position.
290 * @param y Y position.
291 * @param w Width.
292 * @param h Height.
293 * @return The new window handle.
294 * @ingroup Ecore_X_Window_Create_Group
295 */
296EAPI Ecore_X_Window
297ecore_x_window_override_argb_new(Ecore_X_Window parent,
298 int x,
299 int y,
300 int w,
301 int h)
302{
303 Ecore_X_Window win = 0;
304
305 LOGFN(__FILE__, __LINE__, __FUNCTION__);
306
307 win = _ecore_xcb_window_argb_internal_new(parent, x, y, w, h, 1, 0);
308
309 return win;
310}
311
312/**
313 * @defgroup Ecore_X_Window_Destroy_Group X Window Destroy Functions
314 *
315 * Functions to destroy X windows.
316 */
317
318/**
319 * Deletes the given window.
320 * @param win The given window.
321 * @ingroup Ecore_X_Window_Destroy_Group
322 */
323EAPI void
324ecore_x_window_free(Ecore_X_Window win)
325{
326 LOGFN(__FILE__, __LINE__, __FUNCTION__);
327 CHECK_XCB_CONN;
328
329 if (win)
330 {
331 /* xcb_destroy_notify_event_t ev; */
332 /* Ecore_X_Window root; */
333
334 /* if (xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).rem == 1) */
335 /* root = ((xcb_screen_t *)_ecore_xcb_screen)->root; */
336 /* else */
337 /* { */
338 /* xcb_get_geometry_cookie_t cookie; */
339 /* xcb_get_geometry_reply_t *reply; */
340
341 /* cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win); */
342 /* reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL); */
343 /* if (!reply) return; */
344 /* root = reply->root; */
345 /* free(reply); */
346 /* } */
347
348 /* memset(&ev, 0, sizeof(xcb_destroy_notify_event_t)); */
349
350 /* ev.response_type = XCB_DESTROY_NOTIFY; */
351 /* ev.window = win; */
352 /* ev.event = root; */
353
354 /* xcb_send_event(_ecore_xcb_conn, 0, root, */
355 /* XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | */
356 /* XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, */
357 /* (const char *)&ev); */
358
359 xcb_destroy_window(_ecore_xcb_conn, win);
360// ecore_x_flush();
361 }
362}
363
364/**
365 * Sends a delete request to the given window.
366 * @param win The given window.
367 * @ingroup Ecore_X_Window_Destroy_Group
368 */
369EAPI void
370ecore_x_window_delete_request_send(Ecore_X_Window win)
371{
372 LOGFN(__FILE__, __LINE__, __FUNCTION__);
373
374 if (!win) return;
375 ecore_x_client_message32_send(win, ECORE_X_ATOM_WM_PROTOCOLS,
376 XCB_EVENT_MASK_NO_EVENT,
377 ECORE_X_ATOM_WM_DELETE_WINDOW,
378 XCB_CURRENT_TIME, 0, 0, 0);
379}
380
381EAPI void
382ecore_x_window_configure(Ecore_X_Window win,
383 Ecore_X_Window_Configure_Mask mask,
384 int x,
385 int y,
386 int w,
387 int h,
388 int border_width,
389 Ecore_X_Window sibling,
390 int stack_mode)
391{
392 uint16_t vmask = 0;
393 uint32_t vlist[7];
394 unsigned int i = 0;
395
396 LOGFN(__FILE__, __LINE__, __FUNCTION__);
397 CHECK_XCB_CONN;
398
399 if (!win) return;
400
401 if (mask & XCB_CONFIG_WINDOW_X)
402 {
403 vmask |= XCB_CONFIG_WINDOW_X;
404 vlist[i++] = x;
405 }
406 if (mask & XCB_CONFIG_WINDOW_Y)
407 {
408 vmask |= XCB_CONFIG_WINDOW_Y;
409 vlist[i++] = y;
410 }
411 if (mask & XCB_CONFIG_WINDOW_WIDTH)
412 {
413 vmask |= XCB_CONFIG_WINDOW_WIDTH;
414 vlist[i++] = w;
415 }
416 if (mask & XCB_CONFIG_WINDOW_HEIGHT)
417 {
418 vmask |= XCB_CONFIG_WINDOW_HEIGHT;
419 vlist[i++] = h;
420 }
421 if (mask & XCB_CONFIG_WINDOW_BORDER_WIDTH)
422 {
423 vmask |= XCB_CONFIG_WINDOW_BORDER_WIDTH;
424 vlist[i++] = border_width;
425 }
426 if (mask & XCB_CONFIG_WINDOW_SIBLING)
427 {
428 vmask |= XCB_CONFIG_WINDOW_SIBLING;
429 vlist[i++] = sibling;
430 }
431 if (mask & XCB_CONFIG_WINDOW_STACK_MODE)
432 {
433 vmask |= XCB_CONFIG_WINDOW_STACK_MODE;
434 vlist[i++] = stack_mode;
435 }
436
437 xcb_configure_window(_ecore_xcb_conn, win, vmask,
438 (const uint32_t *)&vlist);
439// ecore_x_flush();
440}
441
442/**
443 * @defgroup Ecore_X_Window_Geometry_Group X Window Geometry Functions
444 *
445 * Functions that change or retrieve the geometry of X windows.
446 */
447
448/**
449 * Moves a window to the position @p x, @p y.
450 *
451 * The position is relative to the upper left hand corner of the
452 * parent window.
453 *
454 * @param win The window to move.
455 * @param x X position.
456 * @param y Y position.
457 * @ingroup Ecore_X_Window_Geometry_Group
458 */
459EAPI void
460ecore_x_window_move(Ecore_X_Window win,
461 int x,
462 int y)
463{
464 uint32_t list[2], mask;
465
466 LOGFN(__FILE__, __LINE__, __FUNCTION__);
467 CHECK_XCB_CONN;
468
469 if (!win) return;
470
471 mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y);
472 list[0] = x;
473 list[1] = y;
474
475 xcb_configure_window(_ecore_xcb_conn, win, mask,
476 (const uint32_t *)&list);
477// ecore_x_flush();
478}
479
480/**
481 * Resizes a window.
482 * @param win The window to resize.
483 * @param w New width of the window.
484 * @param h New height of the window.
485 * @ingroup Ecore_X_Window_Geometry_Group
486 */
487EAPI void
488ecore_x_window_resize(Ecore_X_Window win,
489 int w,
490 int h)
491{
492 uint32_t list[2], mask;
493
494 LOGFN(__FILE__, __LINE__, __FUNCTION__);
495 CHECK_XCB_CONN;
496
497 if (!win) return;
498 if (w < 1) w = 1;
499 if (h < 1) h = 1;
500
501 mask = (XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT);
502 list[0] = w;
503 list[1] = h;
504
505 xcb_configure_window(_ecore_xcb_conn, win, mask,
506 (const uint32_t *)&list);
507// ecore_x_flush();
508}
509
510/**
511 * Moves and resizes a window.
512 * @param win The window to move and resize.
513 * @param x New X position of the window.
514 * @param y New Y position of the window.
515 * @param w New width of the window.
516 * @param h New height of the window.
517 * @ingroup Ecore_X_Window_Geometry_Group
518 */
519EAPI void
520ecore_x_window_move_resize(Ecore_X_Window win,
521 int x,
522 int y,
523 int w,
524 int h)
525{
526 uint32_t list[4], mask;
527
528 LOGFN(__FILE__, __LINE__, __FUNCTION__);
529 CHECK_XCB_CONN;
530
531 if (!win) return;
532 if (w < 1) w = 1;
533 if (h < 1) h = 1;
534
535 mask = (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
536 XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT);
537 list[0] = x;
538 list[1] = y;
539 list[2] = w;
540 list[3] = h;
541
542 xcb_configure_window(_ecore_xcb_conn, win, mask,
543 (const uint32_t *)&list);
544// ecore_x_flush();
545}
546
547/**
548 * Retrieves the width of the border of the given window.
549 * @param win The given window.
550 * @return Width of the border of @p win.
551 * @ingroup Ecore_X_Window_Geometry_Group
552 */
553EAPI int
554ecore_x_window_border_width_get(Ecore_X_Window win)
555{
556 LOGFN(__FILE__, __LINE__, __FUNCTION__);
557
558 if (!win) return 0;
559 return ecore_x_drawable_border_width_get(win);
560}
561
562/**
563 * Sets the width of the border of the given window.
564 * @param win The given window.
565 * @param width The new border width.
566 * @ingroup Ecore_X_Window_Geometry_Group
567 */
568EAPI void
569ecore_x_window_border_width_set(Ecore_X_Window win,
570 int border_width)
571{
572 uint32_t list;
573
574 LOGFN(__FILE__, __LINE__, __FUNCTION__);
575 CHECK_XCB_CONN;
576
577 if (!win) return;
578
579 list = border_width;
580
581 xcb_configure_window(_ecore_xcb_conn, win,
582 XCB_CONFIG_WINDOW_BORDER_WIDTH, &list);
583// ecore_x_flush();
584}
585
586/**
587 * @defgroup Ecore_X_Window_Z_Order_Group X Window Z Order Functions
588 *
589 * Functions that change the Z order of X windows.
590 */
591
592/**
593 * Raises the given window.
594 * @param win The window to raise.
595 * @ingroup Ecore_X_Window_Z_Order_Group
596 */
597EAPI void
598ecore_x_window_raise(Ecore_X_Window win)
599{
600 uint32_t list[] = { XCB_STACK_MODE_ABOVE };
601
602 LOGFN(__FILE__, __LINE__, __FUNCTION__);
603 CHECK_XCB_CONN;
604
605 xcb_configure_window(_ecore_xcb_conn, win,
606 XCB_CONFIG_WINDOW_STACK_MODE, list);
607// ecore_x_flush();
608}
609
610/**
611 * Lowers the given window.
612 * @param win The window to lower.
613 * @ingroup Ecore_X_Window_Z_Order_Group
614 */
615EAPI void
616ecore_x_window_lower(Ecore_X_Window win)
617{
618 uint32_t list[] = { XCB_STACK_MODE_BELOW };
619
620 LOGFN(__FILE__, __LINE__, __FUNCTION__);
621 CHECK_XCB_CONN;
622
623 xcb_configure_window(_ecore_xcb_conn, win,
624 XCB_CONFIG_WINDOW_STACK_MODE, list);
625// ecore_x_flush();
626}
627
628/**
629 * Retrieves the depth of the given window.
630 * @param win The given window.
631 * @return Depth of the window.
632 */
633EAPI int
634ecore_x_window_depth_get(Ecore_X_Window win)
635{
636 LOGFN(__FILE__, __LINE__, __FUNCTION__);
637
638 return ecore_x_drawable_depth_get(win);
639}
640
641/**
642 * @defgroup Ecore_X_Window_Properties_Group X Window Property Functions
643 *
644 * Functions that set window properties.
645 */
646
647/**
648 * Sets the default properties for the given window.
649 *
650 * The default properties set for the window are @c WM_CLIENT_MACHINE and
651 * @c _NET_WM_PID.
652 *
653 * @param win The given window.
654 * @ingroup Ecore_X_Window_Properties_Groups
655 */
656EAPI void
657ecore_x_window_defaults_set(Ecore_X_Window win)
658{
659 char buff[MAXHOSTNAMELEN], **argv;
660 int argc;
661 pid_t pid;
662
663 LOGFN(__FILE__, __LINE__, __FUNCTION__);
664 CHECK_XCB_CONN;
665
666 gethostname(buff, MAXHOSTNAMELEN);
667 buff[MAXHOSTNAMELEN - 1] = '\0';
668
669 xcb_change_property(_ecore_xcb_conn, XCB_PROP_MODE_REPLACE, win,
670 ECORE_X_ATOM_WM_CLIENT_MACHINE, ECORE_X_ATOM_STRING,
671 8, strlen(buff), buff);
672
673 pid = getpid();
674 ecore_x_netwm_pid_set(win, pid);
675 ecore_x_netwm_window_type_set(win, ECORE_X_WINDOW_TYPE_NORMAL);
676 ecore_app_args_get(&argc, &argv);
677 ecore_x_icccm_command_set(win, argc, argv);
678}
679
680/**
681 * @defgroup Ecore_X_Window_Visibility_Group X Window Visibility Functions
682 *
683 * Functions to access and change the visibility of X windows.
684 */
685
686/**
687 * Shows a window.
688 *
689 * Synonymous to "mapping" a window in X Window System terminology.
690 *
691 * @param win The window to show.
692 * @ingroup Ecore_X_Window_Visibility
693 */
694EAPI void
695ecore_x_window_show(Ecore_X_Window win)
696{
697 LOGFN(__FILE__, __LINE__, __FUNCTION__);
698 CHECK_XCB_CONN;
699
700 if (win)
701 xcb_map_window(_ecore_xcb_conn, win);
702}
703
704/**
705 * Hides a window.
706 *
707 * Synonymous to "unmapping" a window in X Window System terminology.
708 *
709 * @param win The window to hide.
710 * @ingroup Ecore_X_Window_Visibility
711 */
712EAPI void
713ecore_x_window_hide(Ecore_X_Window win)
714{
715 LOGFN(__FILE__, __LINE__, __FUNCTION__);
716 CHECK_XCB_CONN;
717
718 if (win)
719 {
720 xcb_unmap_notify_event_t ev;
721 Ecore_X_Window root;
722
723 if (xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn)).rem == 1)
724 root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
725 else
726 {
727 xcb_get_geometry_cookie_t cookie;
728 xcb_get_geometry_reply_t *reply;
729
730 cookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win);
731 reply = xcb_get_geometry_reply(_ecore_xcb_conn, cookie, NULL);
732 if (!reply) return;
733 root = reply->root;
734 free(reply);
735 }
736
737 memset(&ev, 0, sizeof(xcb_unmap_notify_event_t));
738
739 ev.response_type = XCB_UNMAP_NOTIFY;
740 ev.window = win;
741 ev.event = root;
742 ev.from_configure = 0;
743
744 xcb_send_event(_ecore_xcb_conn, 0, root,
745 (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
746 XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT),
747 (const char *)&ev);
748
749 xcb_unmap_window(_ecore_xcb_conn, win);
750// ecore_x_flush();
751 }
752}
753
754/**
755 * @defgroup Ecore_X_Window_Focus_Functions X Window Focus Functions
756 *
757 * Functions that give the focus to an X Window.
758 */
759
760/**
761 * Sets the focus to the window @p win.
762 * @param win The window to focus.
763 * @ingroup Ecore_X_Window_Focus_Functions
764 */
765EAPI void
766ecore_x_window_focus(Ecore_X_Window win)
767{
768 LOGFN(__FILE__, __LINE__, __FUNCTION__);
769 CHECK_XCB_CONN;
770
771 if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
772
773 xcb_set_input_focus(_ecore_xcb_conn,
774 XCB_INPUT_FOCUS_PARENT, win, XCB_CURRENT_TIME);
775// ecore_x_flush();
776}
777
778/**
779 * Sets the focus to the given window at a specific time.
780 * @param win The window to focus.
781 * @param t When to set the focus to the window.
782 * @ingroup Ecore_X_Window_Focus_Functions
783 */
784EAPI void
785ecore_x_window_focus_at_time(Ecore_X_Window win,
786 Ecore_X_Time time)
787{
788 LOGFN(__FILE__, __LINE__, __FUNCTION__);
789 CHECK_XCB_CONN;
790
791 if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
792 xcb_set_input_focus(_ecore_xcb_conn, XCB_INPUT_FOCUS_PARENT, win, time);
793// ecore_x_flush();
794}
795
796/**
797 * @defgroup Ecore_X_Window_Parent_Group X Window Parent Functions
798 *
799 * Functions that retrieve or changes the parent window of a window.
800 */
801
802/**
803 * Moves a window to within another window at a given position.
804 * @param win The window to reparent.
805 * @param new_parent The new parent window.
806 * @param x X position within new parent window.
807 * @param y Y position within new parent window.
808 * @ingroup Ecore_X_Window_Parent_Group
809 */
810EAPI void
811ecore_x_window_reparent(Ecore_X_Window win,
812 Ecore_X_Window parent,
813 int x,
814 int y)
815{
816 LOGFN(__FILE__, __LINE__, __FUNCTION__);
817 CHECK_XCB_CONN;
818
819 if (parent == 0)
820 parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
821
822 xcb_reparent_window(_ecore_xcb_conn, win, parent, x, y);
823// ecore_x_flush();
824}
825
826EAPI void
827ecore_x_window_pixmap_set(Ecore_X_Window win,
828 Ecore_X_Pixmap pixmap)
829{
830 uint32_t list;
831
832 LOGFN(__FILE__, __LINE__, __FUNCTION__);
833 CHECK_XCB_CONN;
834
835 list = pixmap;
836
837 xcb_change_window_attributes(_ecore_xcb_conn, win,
838 XCB_CW_BACK_PIXMAP, &list);
839// ecore_x_flush();
840}
841
842/**
843 * Sets the background color of the given window.
844 * @param win The given window
845 * @param r red value (0...65536, 16 bits)
846 * @param g green value (0...65536, 16 bits)
847 * @param b blue value (0...65536, 16 bits)
848 */
849EAPI void
850ecore_x_window_background_color_set(Ecore_X_Window win,
851 unsigned short red,
852 unsigned short green,
853 unsigned short blue)
854{
855 xcb_alloc_color_cookie_t cookie;
856 xcb_alloc_color_reply_t *reply;
857 uint32_t list;
858
859 LOGFN(__FILE__, __LINE__, __FUNCTION__);
860 CHECK_XCB_CONN;
861
862 cookie =
863 xcb_alloc_color_unchecked(_ecore_xcb_conn,
864 ((xcb_screen_t *)_ecore_xcb_screen)->default_colormap,
865 red, green, blue);
866 reply = xcb_alloc_color_reply(_ecore_xcb_conn, cookie, NULL);
867 if (!reply) return;
868 list = reply->pixel;
869 free(reply);
870
871 xcb_change_window_attributes(_ecore_xcb_conn, win,
872 XCB_CW_BACK_PIXEL, &list);
873// ecore_x_flush();
874}
875
876EAPI void
877ecore_x_window_pixel_gravity_set(Ecore_X_Window win,
878 Ecore_X_Gravity gravity)
879{
880 uint32_t list;
881
882 LOGFN(__FILE__, __LINE__, __FUNCTION__);
883 CHECK_XCB_CONN;
884
885 list = gravity;
886
887 xcb_change_window_attributes(_ecore_xcb_conn, win,
888 XCB_CW_BIT_GRAVITY, &list);
889// ecore_x_flush();
890}
891
892EAPI void
893ecore_x_window_gravity_set(Ecore_X_Window win,
894 Ecore_X_Gravity gravity)
895{
896 uint32_t list;
897
898 LOGFN(__FILE__, __LINE__, __FUNCTION__);
899 CHECK_XCB_CONN;
900
901 list = gravity;
902
903 xcb_change_window_attributes(_ecore_xcb_conn, win,
904 XCB_CW_WIN_GRAVITY, &list);
905// ecore_x_flush();
906}
907
908EAPI void
909ecore_x_window_override_set(Ecore_X_Window win,
910 Eina_Bool override)
911{
912 uint32_t list;
913
914 LOGFN(__FILE__, __LINE__, __FUNCTION__);
915 CHECK_XCB_CONN;
916
917 list = override;
918
919 xcb_change_window_attributes(_ecore_xcb_conn, win,
920 XCB_CW_OVERRIDE_REDIRECT, &list);
921// ecore_x_flush();
922}
923
924/**
925 * To be documented.
926 *
927 * FIXME: To be fixed.
928 */
929EAPI void
930ecore_x_window_cursor_show(Ecore_X_Window win,
931 Eina_Bool show)
932{
933 uint32_t list = 0;
934
935 LOGFN(__FILE__, __LINE__, __FUNCTION__);
936 CHECK_XCB_CONN;
937
938 if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
939
940 if (!show)
941 {
942 Ecore_X_Cursor cursor;
943 Ecore_X_Pixmap p, m;
944 Ecore_X_GC gc;
945 xcb_point_t point;
946
947 p = xcb_generate_id(_ecore_xcb_conn);
948 xcb_create_pixmap(_ecore_xcb_conn, 1, p, win, 1, 1);
949 m = xcb_generate_id(_ecore_xcb_conn);
950 xcb_create_pixmap(_ecore_xcb_conn, 1, m, win, 1, 1);
951 gc = xcb_generate_id(_ecore_xcb_conn);
952 xcb_create_gc(_ecore_xcb_conn, gc, win, 0, NULL);
953 xcb_change_gc(_ecore_xcb_conn, gc, XCB_GC_FOREGROUND, &list);
954 point.x = 0;
955 point.y = 0;
956 xcb_poly_point(_ecore_xcb_conn, XCB_COORD_MODE_ORIGIN,
957 win, gc, 1, &point);
958 xcb_free_gc(_ecore_xcb_conn, gc);
959
960 cursor = xcb_generate_id(_ecore_xcb_conn);
961 xcb_create_cursor(_ecore_xcb_conn, cursor,
962 p, m, 0, 0, 0, 0, 0, 0, 0, 0);
963 list = cursor;
964
965 xcb_change_window_attributes(_ecore_xcb_conn, win,
966 XCB_CW_CURSOR, &list);
967
968 xcb_free_cursor(_ecore_xcb_conn, cursor);
969 xcb_free_pixmap(_ecore_xcb_conn, m);
970 xcb_free_pixmap(_ecore_xcb_conn, p);
971 }
972 else
973 {
974 xcb_change_window_attributes(_ecore_xcb_conn, win,
975 XCB_CW_CURSOR, &list);
976 }
977// ecore_x_flush();
978}
979
980EAPI void
981ecore_x_window_cursor_set(Ecore_X_Window win,
982 Ecore_X_Cursor cursor)
983{
984 uint32_t list;
985
986 LOGFN(__FILE__, __LINE__, __FUNCTION__);
987 CHECK_XCB_CONN;
988
989 list = cursor;
990
991 xcb_change_window_attributes(_ecore_xcb_conn, win, XCB_CW_CURSOR, &list);
992// ecore_x_flush();
993}
994
995EAPI void
996ecore_x_window_container_manage(Ecore_X_Window win)
997{
998 uint32_t list;
999
1000 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1001 CHECK_XCB_CONN;
1002
1003 list = (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
1004 XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY);
1005
1006 xcb_change_window_attributes(_ecore_xcb_conn, win,
1007 XCB_CW_EVENT_MASK, &list);
1008// ecore_x_flush();
1009}
1010
1011EAPI void
1012ecore_x_window_client_manage(Ecore_X_Window win)
1013{
1014 uint32_t list;
1015
1016 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1017 CHECK_XCB_CONN;
1018
1019 list = (XCB_EVENT_MASK_VISIBILITY_CHANGE |
1020 XCB_EVENT_MASK_FOCUS_CHANGE |
1021 XCB_EVENT_MASK_PROPERTY_CHANGE |
1022 XCB_EVENT_MASK_COLOR_MAP_CHANGE |
1023 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
1024 XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY);
1025
1026 xcb_change_window_attributes(_ecore_xcb_conn, win,
1027 XCB_CW_EVENT_MASK, &list);
1028
1029#ifdef ECORE_XCB_SHAPE
1030 xcb_shape_select_input(_ecore_xcb_conn, win, EINA_TRUE);
1031#endif
1032// ecore_x_flush();
1033}
1034
1035EAPI void
1036ecore_x_window_sniff(Ecore_X_Window win)
1037{
1038 uint32_t list;
1039
1040 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1041 CHECK_XCB_CONN;
1042
1043 list = (XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
1044 XCB_EVENT_MASK_PROPERTY_CHANGE);
1045
1046 xcb_change_window_attributes(_ecore_xcb_conn, win,
1047 XCB_CW_EVENT_MASK, &list);
1048// ecore_x_flush();
1049}
1050
1051EAPI void
1052ecore_x_window_client_sniff(Ecore_X_Window win)
1053{
1054 uint32_t list;
1055
1056 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1057 CHECK_XCB_CONN;
1058
1059 list = (XCB_EVENT_MASK_VISIBILITY_CHANGE |
1060 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
1061 XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
1062 XCB_EVENT_MASK_FOCUS_CHANGE |
1063 XCB_EVENT_MASK_PROPERTY_CHANGE |
1064 XCB_EVENT_MASK_COLOR_MAP_CHANGE);
1065
1066 xcb_change_window_attributes(_ecore_xcb_conn, win,
1067 XCB_CW_EVENT_MASK, &list);
1068#ifdef ECORE_XCB_SHAPE
1069 xcb_shape_select_input(_ecore_xcb_conn, win, EINA_TRUE);
1070#endif
1071// ecore_x_flush();
1072}
1073
1074EAPI void
1075ecore_x_window_area_clear(Ecore_X_Window win,
1076 int x,
1077 int y,
1078 int w,
1079 int h)
1080{
1081 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1082 CHECK_XCB_CONN;
1083
1084 xcb_clear_area(_ecore_xcb_conn, 0, win, x, y, w, h);
1085// ecore_x_flush();
1086}
1087
1088EAPI void
1089ecore_x_window_area_expose(Ecore_X_Window win,
1090 int x,
1091 int y,
1092 int w,
1093 int h)
1094{
1095 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1096 CHECK_XCB_CONN;
1097
1098 xcb_clear_area(_ecore_xcb_conn, 1, win, x, y, w, h);
1099// ecore_x_flush();
1100}
1101
1102EAPI void
1103ecore_x_window_save_set_add(Ecore_X_Window win)
1104{
1105 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1106 CHECK_XCB_CONN;
1107
1108 xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_INSERT, win);
1109}
1110
1111EAPI void
1112ecore_x_window_save_set_del(Ecore_X_Window win)
1113{
1114 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1115 CHECK_XCB_CONN;
1116
1117 xcb_change_save_set(_ecore_xcb_conn, XCB_SET_MODE_DELETE, win);
1118}
1119
1120/**
1121 * gets the focus to the window @p win.
1122 * @return The window that has focus.
1123 * @ingroup Ecore_X_Window_Focus_Functions
1124 */
1125EAPI Ecore_X_Window
1126ecore_x_window_focus_get(void)
1127{
1128 xcb_get_input_focus_cookie_t cookie;
1129 xcb_get_input_focus_reply_t *reply;
1130 Ecore_X_Window focus = 0;
1131
1132 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1133 CHECK_XCB_CONN;
1134
1135 cookie = xcb_get_input_focus_unchecked(_ecore_xcb_conn);
1136 reply = xcb_get_input_focus_reply(_ecore_xcb_conn, cookie, NULL);
1137 if (!reply) return 0;
1138 focus = reply->focus;
1139 free(reply);
1140 return focus;
1141}
1142
1143EAPI int
1144ecore_x_window_argb_get(Ecore_X_Window win)
1145{
1146 uint8_t ret = 0;
1147#ifdef ECORE_XCB_RENDER
1148 Ecore_X_Visual visual;
1149#endif
1150
1151 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1152 CHECK_XCB_CONN;
1153
1154// if (!win) return ret;
1155
1156#ifdef ECORE_XCB_RENDER
1157 /* grab the window's visual */
1158 visual = _ecore_xcb_window_visual_get(win);
1159
1160 /* check if this visual supports alpha */
1161 ret = _ecore_xcb_render_visual_supports_alpha(visual);
1162#endif
1163
1164 return ret;
1165}
1166
1167EAPI Eina_Bool
1168ecore_x_window_manage(Ecore_X_Window win)
1169{
1170 xcb_get_window_attributes_cookie_t cookie;
1171 xcb_get_window_attributes_reply_t *reply;
1172 xcb_void_cookie_t change_cookie;
1173 xcb_generic_error_t *err;
1174 uint32_t list;
1175
1176 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1177 CHECK_XCB_CONN;
1178
1179 cookie = xcb_get_window_attributes(_ecore_xcb_conn, win);
1180 reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
1181 if (!reply) return EINA_FALSE;
1182
1183 ecore_x_sync(); // needed
1184
1185 list = (XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
1186 XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_RESIZE_REDIRECT |
1187 XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
1188 XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
1189 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
1190 XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
1191 reply->your_event_mask);
1192 free(reply);
1193
1194 change_cookie = xcb_change_window_attributes(_ecore_xcb_conn, win,
1195 XCB_CW_EVENT_MASK, &list);
1196
1197 ecore_x_sync(); // needed
1198
1199 err = xcb_request_check(_ecore_xcb_conn, change_cookie);
1200 if (err)
1201 {
1202 _ecore_xcb_error_handle(err);
1203 free(err);
1204 return EINA_FALSE;
1205 }
1206
1207 return EINA_TRUE;
1208}
1209
1210EAPI Eina_Bool
1211ecore_x_window_attributes_get(Ecore_X_Window win,
1212 Ecore_X_Window_Attributes *att_ret)
1213{
1214 xcb_get_window_attributes_cookie_t cookie;
1215 xcb_get_window_attributes_reply_t *reply;
1216 xcb_get_geometry_cookie_t gcookie;
1217 xcb_get_geometry_reply_t *greply;
1218
1219 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1220 CHECK_XCB_CONN;
1221
1222 cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win);
1223 reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
1224 if (!reply) return EINA_FALSE;
1225
1226 memset(att_ret, 0, sizeof(Ecore_X_Window_Attributes));
1227
1228 if (reply->map_state != XCB_MAP_STATE_UNMAPPED)
1229 att_ret->visible = EINA_TRUE;
1230
1231 if (reply->map_state == XCB_MAP_STATE_VIEWABLE)
1232 att_ret->viewable = EINA_TRUE;
1233
1234 if (reply->override_redirect)
1235 att_ret->override = EINA_TRUE;
1236
1237 if (reply->_class == XCB_WINDOW_CLASS_INPUT_ONLY)
1238 att_ret->input_only = EINA_TRUE;
1239
1240 if (reply->save_under)
1241 att_ret->save_under = EINA_TRUE;
1242
1243 att_ret->event_mask.mine = reply->your_event_mask;
1244 att_ret->event_mask.all = reply->all_event_masks;
1245 att_ret->event_mask.no_propagate = reply->do_not_propagate_mask;
1246 att_ret->window_gravity = reply->win_gravity;
1247 att_ret->pixel_gravity = reply->bit_gravity;
1248 att_ret->colormap = reply->colormap;
1249 att_ret->visual = _ecore_xcb_window_find_visual_by_id(reply->visual);
1250
1251 free(reply);
1252
1253 gcookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win);
1254 greply = xcb_get_geometry_reply(_ecore_xcb_conn, gcookie, NULL);
1255 if (!greply) return EINA_TRUE;
1256
1257 /* xcb_translate_coordinates_reply_t *trans; */
1258 /* xcb_query_tree_cookie_t tcookie; */
1259 /* xcb_query_tree_reply_t *treply; */
1260
1261 /* tcookie = xcb_query_tree(_ecore_xcb_conn, win); */
1262 /* treply = xcb_query_tree_reply(_ecore_xcb_conn, tcookie, NULL); */
1263
1264 /* trans = */
1265 /* xcb_translate_coordinates_reply(_ecore_xcb_conn, */
1266 /* xcb_translate_coordinates(_ecore_xcb_conn, */
1267 /* win, treply->parent, greply->x, greply->y), NULL); */
1268 /* free(treply); */
1269
1270 att_ret->root = greply->root;
1271 att_ret->depth = greply->depth;
1272// att_ret->x = trans->dst_x;
1273// att_ret->y = trans->dst_y;
1274 att_ret->x = greply->x;
1275 att_ret->y = greply->y;
1276 att_ret->w = greply->width;
1277 att_ret->h = greply->height;
1278 att_ret->border = greply->border_width;
1279
1280// free(trans);
1281
1282 free(greply);
1283 return EINA_TRUE;
1284}
1285
1286/**
1287 * Retrieves the size of the given window.
1288 * @param win The given window.
1289 * @param w Pointer to an integer into which the width is to be stored.
1290 * @param h Pointer to an integer into which the height is to be stored.
1291 * @ingroup Ecore_X_Window_Geometry_Group
1292 */
1293EAPI void
1294ecore_x_window_size_get(Ecore_X_Window win,
1295 int *width,
1296 int *height)
1297{
1298 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1299 CHECK_XCB_CONN;
1300
1301 if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1302 ecore_x_drawable_geometry_get(win, NULL, NULL, width, height);
1303}
1304
1305/**
1306 * Set if a window should be ignored.
1307 * @param win The given window.
1308 * @param ignore if to ignore
1309 */
1310EAPI void
1311ecore_x_window_ignore_set(Ecore_X_Window win,
1312 int ignore)
1313{
1314 int i = 0, j = 0, count = 0;
1315
1316 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1317 CHECK_XCB_CONN;
1318
1319 if (ignore)
1320 {
1321 if (ignore_list)
1322 {
1323 for (i = 0; i < ignore_num; i++)
1324 if (win == ignore_list[i]) return;
1325
1326 ignore_list =
1327 realloc(ignore_list, (ignore_num + 1) * sizeof(Ecore_X_Window));
1328 if (!ignore_list) return;
1329
1330 ignore_list[ignore_num++] = win;
1331 }
1332 else
1333 {
1334 ignore_num = 0;
1335 ignore_list = malloc(sizeof(Ecore_X_Window));
1336 if (!ignore_list) return;
1337 ignore_list[ignore_num++] = win;
1338 }
1339 }
1340 else
1341 {
1342 if (!ignore_list) return;
1343 for (count = ignore_num, i = 0, j = 0; i < count; i++)
1344 {
1345 if (win != ignore_list[i])
1346 ignore_list[j++] = ignore_list[i];
1347 else
1348 ignore_num--;
1349 }
1350 if (ignore_num <= 0)
1351 {
1352 free(ignore_list);
1353 ignore_list = NULL;
1354 return;
1355 }
1356
1357 ignore_list =
1358 realloc(ignore_list, ignore_num * sizeof(Ecore_X_Window));
1359 }
1360}
1361
1362/**
1363 * Get the ignore list
1364 * @param num number of windows in the list
1365 * @return list of windows to ignore
1366 */
1367EAPI Ecore_X_Window *
1368ecore_x_window_ignore_list(int *num)
1369{
1370 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1371
1372 if (num) *num = ignore_num;
1373 return ignore_list;
1374}
1375
1376/**
1377 * Get a list of all the root windows on the server.
1378 *
1379 * @note The returned array will need to be freed after use.
1380 * @param num_ret Pointer to integer to put number of windows returned in.
1381 * @return An array of all the root windows. @c NULL is returned if memory
1382 * could not be allocated for the list, or if @p num_ret is @c NULL.
1383 */
1384EAPI Ecore_X_Window *
1385ecore_x_window_root_list(int *num_ret)
1386{
1387 xcb_screen_iterator_t iter;
1388 uint8_t i, num;
1389 Ecore_X_Window *roots = NULL;
1390#ifdef ECORE_XCB_XPRINT
1391 const xcb_query_extension_reply_t *ext_reply;
1392#endif
1393
1394 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1395 CHECK_XCB_CONN;
1396
1397 if (!num_ret) return NULL;
1398 if (num_ret) *num_ret = 0;
1399
1400 /* if (xcb_connection_has_error(_ecore_xcb_conn)) */
1401 /* { */
1402 /* DBG("XCB Connection Has Error !!!"); */
1403 /* return NULL; */
1404 /* } */
1405
1406 num = ecore_x_screen_count_get();
1407
1408#ifdef ECORE_XCB_XPRINT
1409 ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_x_print_id);
1410 if ((ext_reply) && (ext_reply->present))
1411 {
1412 xcb_x_print_print_query_screens_cookie_t cookie;
1413 xcb_x_print_print_query_screens_reply_t *reply;
1414
1415 cookie = xcb_x_print_print_query_screens_unchecked(_ecore_xcb_conn);
1416 reply =
1417 xcb_x_print_print_query_screens_reply(_ecore_xcb_conn, cookie, NULL);
1418 if (reply)
1419 {
1420 xcb_window_t *screens;
1421 int psnum = 0, overlap = 0, j = 0, k = 0;
1422
1423 psnum = xcb_x_print_print_query_screens_roots_length(reply);
1424 screens = xcb_x_print_print_query_screens_roots(reply);
1425 for (i = 0; i < num; i++)
1426 {
1427 for (j = 0; j < psnum; j++)
1428 {
1429 xcb_screen_t *s;
1430
1431 if ((s = _ecore_xcb_window_screen_of_display(i)))
1432 {
1433 if (s->root == screens[j])
1434 overlap++;
1435 }
1436 }
1437 }
1438 if (!(roots = malloc((num - overlap)
1439 * sizeof(Ecore_X_Window)))) return NULL;
1440 for (i = 0; i < num; i++)
1441 {
1442 Eina_Bool is_print = EINA_FALSE;
1443
1444 for (j = 0; j < psnum; j++)
1445 {
1446 xcb_screen_t *s;
1447
1448 if ((s = _ecore_xcb_window_screen_of_display(i)))
1449 {
1450 if (s->root == screens[j])
1451 {
1452 is_print = EINA_TRUE;
1453 break;
1454 }
1455 }
1456 }
1457 if (!is_print)
1458 {
1459 xcb_screen_t *s;
1460
1461 if ((s = _ecore_xcb_window_screen_of_display(i)))
1462 {
1463 roots[k] = s->root;
1464 k++;
1465 }
1466 }
1467 }
1468 if (num_ret) *num_ret = k;
1469 free(reply);
1470 }
1471 else
1472 {
1473 /* Fallback to default method */
1474 iter =
1475 xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
1476 if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL;
1477 if (num_ret) *num_ret = num;
1478 for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
1479 roots[i] = iter.data->root;
1480 }
1481 }
1482 else
1483 {
1484 /* Fallback to default method */
1485 iter =
1486 xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
1487 if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL;
1488 if (num_ret) *num_ret = num;
1489 for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
1490 roots[i] = iter.data->root;
1491 }
1492#else
1493 iter =
1494 xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
1495 if (!(roots = malloc(num * sizeof(Ecore_X_Window)))) return NULL;
1496 if (num_ret) *num_ret = num;
1497 for (i = 0; iter.rem; xcb_screen_next(&iter), i++)
1498 roots[i] = iter.data->root;
1499#endif
1500
1501 return roots;
1502}
1503
1504EAPI Ecore_X_Window *
1505ecore_x_window_children_get(Ecore_X_Window win,
1506 int *num)
1507{
1508 xcb_query_tree_cookie_t cookie;
1509 xcb_query_tree_reply_t *reply;
1510 Ecore_X_Window *windows = NULL;
1511
1512 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1513 CHECK_XCB_CONN;
1514
1515 if (num) *num = 0;
1516 cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, win);
1517 reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
1518 if (!reply) return NULL;
1519
1520 if (num) *num = reply->children_len;
1521 if (reply->children_len > 0)
1522 {
1523 windows = malloc(sizeof(Ecore_X_Window) * reply->children_len);
1524 if (windows)
1525 {
1526 unsigned int i = 0;
1527 xcb_window_t *w;
1528
1529 w = xcb_query_tree_children(reply);
1530 for (i = 0; i < reply->children_len; i++)
1531 windows[i] = w[i];
1532 }
1533 }
1534
1535 free(reply);
1536 return windows;
1537}
1538
1539/**
1540 * Retrieves the root window a given window is on.
1541 * @param win The window to get the root window of
1542 * @return The root window of @p win
1543 * @ingroup Ecore_X_Window_Geometry_Group
1544 */
1545EAPI Ecore_X_Window
1546ecore_x_window_root_get(Ecore_X_Window win)
1547{
1548 xcb_get_geometry_cookie_t gcookie;
1549 xcb_get_geometry_reply_t *greply;
1550 Ecore_X_Window window = 0;
1551
1552 /* LOGFN(__FILE__, __LINE__, __FUNCTION__); */
1553 CHECK_XCB_CONN;
1554
1555 gcookie = xcb_get_geometry_unchecked(_ecore_xcb_conn, win);
1556 greply = xcb_get_geometry_reply(_ecore_xcb_conn, gcookie, NULL);
1557 if (!greply) return 0;
1558 window = greply->root;
1559 free(greply);
1560
1561 return window;
1562}
1563
1564EAPI Ecore_X_Window
1565ecore_x_window_root_first_get(void)
1566{
1567 return ((xcb_screen_t *)_ecore_xcb_screen)->root;
1568}
1569
1570/**
1571 * Retrieves the geometry of the given window.
1572 *
1573 * Note that the x & y coordingates are relative to your parent. In
1574 * particular for reparenting window managers - relative to you window border.
1575 * If you want screen coordinates either walk the window tree to the root,
1576 * else for ecore_evas applications see ecore_evas_geometry_get(). Elementary
1577 * applications can use elm_win_screen_position_get().
1578 *
1579 * @param win The given window.
1580 * @param x Pointer to an integer in which the X position is to be stored.
1581 * @param y Pointer to an integer in which the Y position is to be stored.
1582 * @param w Pointer to an integer in which the width is to be stored.
1583 * @param h Pointer to an integer in which the height is to be stored.
1584 * @ingroup Ecore_X_Window_Geometry_Group
1585 */
1586EAPI void
1587ecore_x_window_geometry_get(Ecore_X_Window win,
1588 int *x,
1589 int *y,
1590 int *w,
1591 int *h)
1592{
1593 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1594 CHECK_XCB_CONN;
1595
1596 if (!win) win = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1597 ecore_x_drawable_geometry_get(win, x, y, w, h);
1598}
1599
1600/**
1601 * Retrieves the top, visible window at the given location.
1602 * @param x The given X position.
1603 * @param y The given Y position.
1604 * @return The window at that position.
1605 * @ingroup Ecore_X_Window_Geometry_Group
1606 */
1607EAPI Ecore_X_Window
1608ecore_x_window_at_xy_get(int x,
1609 int y)
1610{
1611 Ecore_X_Window root, win = 0;
1612
1613 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1614 CHECK_XCB_CONN;
1615
1616 root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1617
1618 ecore_x_grab();
1619 win = _ecore_xcb_window_at_xy_get(root, 0, 0, x, y, NULL, 0);
1620 ecore_x_ungrab();
1621
1622 return win ? win : root;
1623}
1624
1625/**
1626 * Retrieves the top, visible window at the given location,
1627 * but skips the windows in the list.
1628 * @param x The given X position.
1629 * @param y The given Y position.
1630 * @return The window at that position.
1631 * @ingroup Ecore_X_Window_Geometry_Group
1632 */
1633EAPI Ecore_X_Window
1634ecore_x_window_at_xy_with_skip_get(int x,
1635 int y,
1636 Ecore_X_Window *skip,
1637 int skip_num)
1638{
1639 Ecore_X_Window root, win = 0;
1640
1641 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1642 CHECK_XCB_CONN;
1643
1644 root = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1645
1646 ecore_x_grab();
1647 win = _ecore_xcb_window_at_xy_get(root, 0, 0, x, y, skip, skip_num);
1648 ecore_x_ungrab();
1649
1650 return win ? win : root;
1651}
1652
1653EAPI Ecore_X_Window
1654ecore_x_window_at_xy_begin_get(Ecore_X_Window begin,
1655 int x,
1656 int y)
1657{
1658 Ecore_X_Window win = 0;
1659
1660 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1661 CHECK_XCB_CONN;
1662
1663 ecore_x_grab();
1664 win = _ecore_xcb_window_at_xy_get(begin, 0, 0, x, y, NULL, 0);
1665 ecore_x_ungrab();
1666
1667 return win ? win : begin;
1668}
1669
1670/**
1671 * Retrieves the parent window of the given window.
1672 * @param win The given window.
1673 * @return The parent window of @p win.
1674 * @ingroup Ecore_X_Window_Parent_Group
1675 */
1676EAPI Ecore_X_Window
1677ecore_x_window_parent_get(Ecore_X_Window win)
1678{
1679 xcb_query_tree_cookie_t cookie;
1680 xcb_query_tree_reply_t *reply;
1681 Ecore_X_Window window = 0;
1682
1683 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1684 CHECK_XCB_CONN;
1685
1686// if (!win) return 0;
1687 cookie = xcb_query_tree(_ecore_xcb_conn, win);
1688 reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
1689 if (!reply) return 0;
1690 window = reply->parent;
1691 free(reply);
1692
1693 return window;
1694}
1695
1696/**
1697 * Finds out whether the given window is currently visible.
1698 * @param win The given window.
1699 * @return 1 if the window is visible, otherwise 0.
1700 * @ingroup Ecore_X_Window_Visibility_Group
1701 */
1702EAPI int
1703ecore_x_window_visible_get(Ecore_X_Window win)
1704{
1705 xcb_get_window_attributes_cookie_t cookie;
1706 xcb_get_window_attributes_reply_t *reply;
1707 int ret = EINA_FALSE;
1708
1709 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1710 CHECK_XCB_CONN;
1711
1712 cookie = xcb_get_window_attributes_unchecked(_ecore_xcb_conn, win);
1713 reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
1714 if (!reply) return EINA_FALSE;
1715
1716 if (reply->map_state == XCB_MAP_STATE_VIEWABLE)
1717 ret = EINA_TRUE;
1718
1719 free(reply);
1720 return ret;
1721}
1722
1723EAPI void
1724ecore_x_window_button_grab(Ecore_X_Window win,
1725 int button,
1726 Ecore_X_Event_Mask mask,
1727 int mod,
1728 int any_mod)
1729{
1730 int i = 0;
1731 uint16_t m, locks[8], ev;
1732 uint8_t b;
1733 Ecore_X_Window *t;
1734
1735 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1736 CHECK_XCB_CONN;
1737
1738 b = button;
1739 if (b == 0)
1740 b = XCB_BUTTON_INDEX_ANY;
1741
1742 m = _ecore_xcb_window_modifiers_get(mod);
1743 if (any_mod) m = XCB_MOD_MASK_ANY;
1744
1745 locks[0] = 0;
1746 locks[1] = ECORE_X_LOCK_CAPS;
1747 locks[2] = ECORE_X_LOCK_NUM;
1748 locks[3] = ECORE_X_LOCK_SCROLL;
1749 locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1750 locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1751 locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1752 locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1753
1754 ev = mask;
1755 for (i = 0; i < 8; i++)
1756 xcb_grab_button(_ecore_xcb_conn, 0, win, ev,
1757 XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC,
1758 XCB_NONE, XCB_NONE, b, m | locks[i]);
1759
1760 _ecore_xcb_button_grabs_num++;
1761 t = realloc(_ecore_xcb_button_grabs,
1762 _ecore_xcb_button_grabs_num * sizeof(Ecore_X_Window));
1763 if (!t) return;
1764
1765 _ecore_xcb_button_grabs = t;
1766 _ecore_xcb_button_grabs[_ecore_xcb_button_grabs_num - 1] = win;
1767}
1768
1769EAPI void
1770ecore_x_window_button_ungrab(Ecore_X_Window win,
1771 int button,
1772 int mod,
1773 int any_mod)
1774{
1775 int i = 0;
1776 uint16_t m = 0, locks[8];
1777 uint8_t b;
1778
1779 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1780 CHECK_XCB_CONN;
1781
1782 b = button;
1783 if (b == 0) b = XCB_BUTTON_INDEX_ANY;
1784
1785 m = _ecore_xcb_window_modifiers_get(mod);
1786 if (any_mod) m = XCB_MOD_MASK_ANY;
1787
1788 locks[0] = 0;
1789 locks[1] = ECORE_X_LOCK_CAPS;
1790 locks[2] = ECORE_X_LOCK_NUM;
1791 locks[3] = ECORE_X_LOCK_SCROLL;
1792 locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1793 locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1794 locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1795 locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1796
1797 for (i = 0; i < 8; i++)
1798 xcb_ungrab_button(_ecore_xcb_conn, b, win, m | locks[i]);
1799
1800 _ecore_xcb_sync_magic_send(1, win);
1801}
1802
1803EAPI void
1804ecore_x_window_key_grab(Ecore_X_Window win,
1805 const char *key,
1806 int mod,
1807 int any_mod)
1808{
1809 xcb_keycode_t keycode = XCB_NO_SYMBOL;
1810 uint16_t m = 0, locks[8];
1811 int i = 0;
1812 Ecore_X_Window *t;
1813
1814 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1815 CHECK_XCB_CONN;
1816
1817 keycode = _ecore_xcb_keymap_string_to_keycode(key);
1818 if (keycode == XCB_NO_SYMBOL) return;
1819
1820 m = _ecore_xcb_window_modifiers_get(mod);
1821 if (any_mod) m = XCB_MOD_MASK_ANY;
1822
1823 locks[0] = 0;
1824 locks[1] = ECORE_X_LOCK_CAPS;
1825 locks[2] = ECORE_X_LOCK_NUM;
1826 locks[3] = ECORE_X_LOCK_SCROLL;
1827 locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1828 locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1829 locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1830 locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1831
1832 for (i = 0; i < 8; i++)
1833 xcb_grab_key(_ecore_xcb_conn, 0, win, m | locks[i],
1834 keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
1835 _ecore_xcb_key_grabs_num++;
1836 t = realloc(_ecore_xcb_key_grabs,
1837 _ecore_xcb_key_grabs_num * sizeof(Ecore_X_Window));
1838 if (!t) return;
1839 _ecore_xcb_key_grabs = t;
1840 _ecore_xcb_key_grabs[_ecore_xcb_key_grabs_num - 1] = win;
1841}
1842
1843EAPI void
1844ecore_x_window_key_ungrab(Ecore_X_Window win,
1845 const char *key,
1846 int mod,
1847 int any_mod)
1848{
1849 xcb_keycode_t keycode = XCB_NO_SYMBOL;
1850 uint16_t m = 0, locks[8];
1851 int i = 0;
1852
1853 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1854 CHECK_XCB_CONN;
1855
1856 keycode = _ecore_xcb_keymap_string_to_keycode(key);
1857 if (keycode == XCB_NO_SYMBOL) return;
1858
1859 m = _ecore_xcb_window_modifiers_get(mod);
1860 if (any_mod) m = XCB_MOD_MASK_ANY;
1861
1862 locks[0] = 0;
1863 locks[1] = ECORE_X_LOCK_CAPS;
1864 locks[2] = ECORE_X_LOCK_NUM;
1865 locks[3] = ECORE_X_LOCK_SCROLL;
1866 locks[4] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM;
1867 locks[5] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_SCROLL;
1868 locks[6] = ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1869 locks[7] = ECORE_X_LOCK_CAPS | ECORE_X_LOCK_NUM | ECORE_X_LOCK_SCROLL;
1870
1871 for (i = 0; i < 8; i++)
1872 xcb_ungrab_key(_ecore_xcb_conn, keycode, win, m | locks[i]);
1873
1874 _ecore_xcb_sync_magic_send(2, win);
1875}
1876
1877/* local functions */
1878Ecore_X_Window
1879_ecore_xcb_window_root_of_screen_get(int screen)
1880{
1881 xcb_screen_iterator_t iter;
1882
1883 CHECK_XCB_CONN;
1884 iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
1885 for (; iter.rem; --screen, xcb_screen_next(&iter))
1886 if (screen == 0)
1887 {
1888 xcb_screen_t *s;
1889
1890 if ((s = iter.data))
1891 return s->root;
1892 }
1893 return 0;
1894}
1895
1896static Ecore_X_Window
1897_ecore_xcb_window_argb_internal_new(Ecore_X_Window parent,
1898 int x,
1899 int y,
1900 int w,
1901 int h,
1902 uint8_t override_redirect,
1903 uint8_t save_under)
1904{
1905 Ecore_X_Window win = 0;
1906#ifdef ECORE_XCB_RENDER
1907 uint32_t value_list[10];
1908 uint32_t value_mask;
1909 uint32_t vis;
1910 Ecore_X_Colormap colormap;
1911#endif
1912
1913 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1914 CHECK_XCB_CONN;
1915
1916#ifdef ECORE_XCB_RENDER
1917 if (parent == 0)
1918 parent = ((xcb_screen_t *)_ecore_xcb_screen)->root;
1919
1920 vis =
1921 _ecore_xcb_render_find_visual_id(XCB_RENDER_PICT_TYPE_DIRECT, EINA_TRUE);
1922
1923 colormap = xcb_generate_id(_ecore_xcb_conn);
1924 xcb_create_colormap(_ecore_xcb_conn, XCB_COLORMAP_ALLOC_NONE,
1925 colormap, parent, vis);
1926
1927 value_mask = (XCB_CW_BACK_PIXMAP | XCB_CW_BORDER_PIXEL | XCB_CW_BIT_GRAVITY |
1928 XCB_CW_WIN_GRAVITY | XCB_CW_BACKING_STORE |
1929 XCB_CW_OVERRIDE_REDIRECT | XCB_CW_SAVE_UNDER |
1930 XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE | XCB_CW_COLORMAP);
1931
1932 value_list[0] = XCB_BACK_PIXMAP_NONE;
1933 value_list[1] = 0;
1934 value_list[2] = XCB_GRAVITY_NORTH_WEST;
1935 value_list[3] = XCB_GRAVITY_NORTH_WEST;
1936 value_list[4] = XCB_BACKING_STORE_NOT_USEFUL;
1937 value_list[5] = override_redirect;
1938 value_list[6] = save_under;
1939 value_list[7] = (XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE |
1940 XCB_EVENT_MASK_BUTTON_PRESS |
1941 XCB_EVENT_MASK_BUTTON_RELEASE |
1942 XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
1943 XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_EXPOSURE |
1944 XCB_EVENT_MASK_VISIBILITY_CHANGE |
1945 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
1946 XCB_EVENT_MASK_FOCUS_CHANGE |
1947 XCB_EVENT_MASK_PROPERTY_CHANGE |
1948 XCB_EVENT_MASK_COLOR_MAP_CHANGE);
1949 value_list[8] = XCB_EVENT_MASK_NO_EVENT;
1950 value_list[9] = colormap;
1951
1952 win = xcb_generate_id(_ecore_xcb_conn);
1953 xcb_create_window(_ecore_xcb_conn, 32, win, parent, x, y, w, h, 0,
1954 XCB_WINDOW_CLASS_INPUT_OUTPUT, vis, value_mask,
1955 value_list);
1956
1957 xcb_free_colormap(_ecore_xcb_conn, colormap);
1958
1959 if (parent == ((xcb_screen_t *)_ecore_xcb_screen)->root)
1960 ecore_x_window_defaults_set(win);
1961#endif
1962
1963 return win;
1964}
1965
1966static Ecore_X_Window
1967_ecore_xcb_window_at_xy_get(Ecore_X_Window base,
1968 int bx,
1969 int by,
1970 int x,
1971 int y,
1972 Ecore_X_Window *skip,
1973 int skip_num)
1974{
1975 xcb_query_tree_cookie_t cookie;
1976 xcb_query_tree_reply_t *reply;
1977 Ecore_X_Window *windows = NULL;
1978 int wx, wy, ww, wh, num, i = 0;
1979 Eina_Bool skipit = EINA_FALSE;
1980
1981 LOGFN(__FILE__, __LINE__, __FUNCTION__);
1982 CHECK_XCB_CONN;
1983
1984 if (!ecore_x_window_visible_get(base)) return 0;
1985
1986 ecore_x_window_geometry_get(base, &wx, &wy, &ww, &wh);
1987 wx += bx;
1988 wy += by;
1989
1990 if (!((x >= wx) && (y >= wy) && (x < (wx + ww)) && (y < (wy + wh))))
1991 return 0;
1992
1993 cookie = xcb_query_tree_unchecked(_ecore_xcb_conn, base);
1994 reply = xcb_query_tree_reply(_ecore_xcb_conn, cookie, NULL);
1995 if (!reply) return 0;
1996
1997 num = reply->children_len;
1998 windows = xcb_query_tree_children(reply);
1999
2000 for (i = (num - 1); i >= 0; --i)
2001 {
2002 skipit = EINA_FALSE;
2003
2004 if (skip)
2005 {
2006 int j = 0;
2007
2008 for (j = 0; j < skip_num; j++)
2009 {
2010 if (windows[i] == skip[j])
2011 {
2012 skipit = EINA_TRUE;
2013 goto onward;
2014 }
2015 }
2016 }
2017onward:
2018 if (!skipit)
2019 {
2020 Ecore_X_Window child = 0;
2021
2022 child =
2023 _ecore_xcb_window_at_xy_get(windows[i],
2024 wx, wy, x, y, skip, skip_num);
2025 if (child)
2026 {
2027 if (reply) free(reply);
2028 return child;
2029 }
2030 }
2031 }
2032
2033 if (reply) free(reply);
2034 return base;
2035}
2036
2037Ecore_X_Visual
2038_ecore_xcb_window_visual_get(Ecore_X_Window win)
2039{
2040 xcb_get_window_attributes_cookie_t cookie;
2041 xcb_get_window_attributes_reply_t *reply;
2042 Ecore_X_Visual visual = 0;
2043
2044 CHECK_XCB_CONN;
2045
2046 cookie = xcb_get_window_attributes(_ecore_xcb_conn, win);
2047 reply = xcb_get_window_attributes_reply(_ecore_xcb_conn, cookie, NULL);
2048 if (!reply) return 0;
2049 visual = _ecore_xcb_window_find_visual_by_id(reply->visual);
2050 free(reply);
2051
2052 return visual;
2053}
2054
2055void
2056_ecore_xcb_window_button_grab_remove(Ecore_X_Window win)
2057{
2058 LOGFN(__FILE__, __LINE__, __FUNCTION__);
2059 CHECK_XCB_CONN;
2060
2061 if (_ecore_xcb_button_grabs_num > 0)
2062 {
2063 int i = 0, shuffle = 0;
2064
2065 for (i = 0; i < _ecore_xcb_button_grabs_num; i++)
2066 {
2067 if (shuffle)
2068 _ecore_xcb_button_grabs[i - 1] = _ecore_xcb_button_grabs[i];
2069
2070 if ((!shuffle) && (_ecore_xcb_button_grabs[i] == win))
2071 shuffle = 1;
2072 }
2073
2074 if (shuffle)
2075 {
2076 Ecore_X_Window *t;
2077
2078 _ecore_xcb_button_grabs_num--;
2079 if (_ecore_xcb_button_grabs_num <= 0)
2080 {
2081 free(_ecore_xcb_button_grabs);
2082 _ecore_xcb_button_grabs = NULL;
2083 return;
2084 }
2085
2086 t = realloc(_ecore_xcb_button_grabs,
2087 _ecore_xcb_button_grabs_num * sizeof(Ecore_X_Window));
2088 if (!t) return;
2089 _ecore_xcb_button_grabs = t;
2090 }
2091 }
2092}
2093
2094void
2095_ecore_xcb_window_key_grab_remove(Ecore_X_Window win)
2096{
2097 LOGFN(__FILE__, __LINE__, __FUNCTION__);
2098 CHECK_XCB_CONN;
2099
2100 if (_ecore_xcb_key_grabs_num > 0)
2101 {
2102 int i = 0, shuffle = 0;
2103
2104 for (i = 0; i < _ecore_xcb_key_grabs_num; i++)
2105 {
2106 if (shuffle)
2107 _ecore_xcb_key_grabs[i - 1] = _ecore_xcb_key_grabs[i];
2108
2109 if ((!shuffle) && (_ecore_xcb_key_grabs[i] == win))
2110 shuffle = 1;
2111 }
2112
2113 if (shuffle)
2114 {
2115 Ecore_X_Window *t;
2116
2117 _ecore_xcb_key_grabs_num--;
2118 if (_ecore_xcb_key_grabs_num <= 0)
2119 {
2120 free(_ecore_xcb_key_grabs);
2121 _ecore_xcb_key_grabs = NULL;
2122 return;
2123 }
2124
2125 t = realloc(_ecore_xcb_key_grabs,
2126 _ecore_xcb_key_grabs_num * sizeof(Ecore_X_Window));
2127 if (!t) return;
2128 _ecore_xcb_key_grabs = t;
2129 }
2130 }
2131}
2132
2133void
2134_ecore_xcb_window_grab_allow_events(Ecore_X_Window event_win,
2135 Ecore_X_Window child_win,
2136 int type,
2137 void *event,
2138 Ecore_X_Time timestamp)
2139{
2140 int i = 0;
2141
2142 LOGFN(__FILE__, __LINE__, __FUNCTION__);
2143 CHECK_XCB_CONN;
2144
2145 for (i = 0; i < _ecore_xcb_button_grabs_num; i++)
2146 {
2147 if ((_ecore_xcb_button_grabs[i] == event_win) ||
2148 (_ecore_xcb_button_grabs[i] == child_win))
2149 {
2150 Eina_Bool replay = EINA_FALSE;
2151
2152 if (_ecore_xcb_window_grab_replay_func)
2153 {
2154 replay =
2155 _ecore_xcb_window_grab_replay_func(_ecore_xcb_window_grab_replay_data,
2156 type, event);
2157 }
2158 if (replay)
2159 {
2160 xcb_allow_events(_ecore_xcb_conn,
2161 XCB_ALLOW_REPLAY_POINTER, timestamp);
2162 }
2163 else
2164 {
2165 xcb_allow_events(_ecore_xcb_conn,
2166 XCB_ALLOW_ASYNC_POINTER, timestamp);
2167 }
2168 break;
2169 }
2170 }
2171}
2172
2173static int
2174_ecore_xcb_window_modifiers_get(unsigned int state)
2175{
2176 int xmodifiers = 0;
2177
2178 if (state & ECORE_EVENT_MODIFIER_SHIFT)
2179 xmodifiers |= ECORE_X_MODIFIER_SHIFT;
2180 if (state & ECORE_EVENT_MODIFIER_CTRL)
2181 xmodifiers |= ECORE_X_MODIFIER_CTRL;
2182 if (state & ECORE_EVENT_MODIFIER_ALT)
2183 xmodifiers |= ECORE_X_MODIFIER_ALT;
2184 if (state & ECORE_EVENT_MODIFIER_WIN)
2185 xmodifiers |= ECORE_X_MODIFIER_WIN;
2186 if (state & ECORE_EVENT_LOCK_SCROLL)
2187 xmodifiers |= ECORE_X_LOCK_SCROLL;
2188 if (state & ECORE_EVENT_LOCK_NUM)
2189 xmodifiers |= ECORE_X_LOCK_NUM;
2190 if (state & ECORE_EVENT_LOCK_CAPS)
2191 xmodifiers |= ECORE_X_LOCK_CAPS;
2192 if (state & ECORE_EVENT_LOCK_SHIFT)
2193 xmodifiers |= ECORE_X_LOCK_SHIFT;
2194
2195 return xmodifiers;
2196}
2197
2198static xcb_visualtype_t *
2199_ecore_xcb_window_find_visual_by_id(xcb_visualid_t id)
2200{
2201 xcb_depth_iterator_t diter;
2202 xcb_visualtype_iterator_t viter;
2203
2204 CHECK_XCB_CONN;
2205 diter = xcb_screen_allowed_depths_iterator(_ecore_xcb_screen);
2206 for (; diter.rem; xcb_depth_next(&diter))
2207 {
2208 viter = xcb_depth_visuals_iterator(diter.data);
2209 for (; viter.rem; xcb_visualtype_next(&viter))
2210 {
2211 if (viter.data->visual_id == id)
2212 return viter.data;
2213 }
2214 }
2215 return 0;
2216}
2217
2218#ifdef ECORE_XCB_XPRINT
2219static xcb_screen_t *
2220_ecore_xcb_window_screen_of_display(int screen)
2221{
2222 xcb_screen_iterator_t iter;
2223
2224 CHECK_XCB_CONN;
2225 iter = xcb_setup_roots_iterator(xcb_get_setup(_ecore_xcb_conn));
2226 for (; iter.rem; --screen, xcb_screen_next(&iter))
2227 if (screen == 0)
2228 return iter.data;
2229
2230 return NULL;
2231}
2232
2233#endif