1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif /* ifdef HAVE_CONFIG_H */
4
5 #include <stdlib.h>
6 #include <sys/types.h>
7 #include <unistd.h>
8
9 #include "Ecore.h"
10 #include "ecore_x_private.h"
11 #include "Ecore_X.h"
12 #include "Ecore_X_Atoms.h"
13
14 static int ignore_num = 0;
15 static Ecore_X_Window *ignore_list = NULL;
16
17 /**
18 * @defgroup Ecore_X_Window_Create_Group X Window Creation Functions
19 * @ingroup Ecore_X_Group
20 *
21 * Functions that can be used to create an X window.
22 */
23
24 EAPI Ecore_X_Window
ecore_x_window_full_new(Ecore_X_Window parent,int x,int y,int w,int h,Ecore_X_Visual * visual,Ecore_X_Colormap colormap,int depth,Eina_Bool override)25 ecore_x_window_full_new(Ecore_X_Window parent,
26 int x,
27 int y,
28 int w,
29 int h,
30 Ecore_X_Visual *visual,
31 Ecore_X_Colormap colormap,
32 int depth,
33 Eina_Bool override)
34 {
35 Window win;
36 XSetWindowAttributes attr;
37
38 LOGFN;
39 if (parent == 0)
40 parent = DefaultRootWindow(_ecore_x_disp);
41
42 attr.backing_store = NotUseful;
43 attr.override_redirect = override;
44 attr.border_pixel = 0;
45 attr.background_pixmap = None;
46 attr.bit_gravity = NorthWestGravity;
47 attr.win_gravity = NorthWestGravity;
48 attr.save_under = False;
49 attr.do_not_propagate_mask = NoEventMask;
50 attr.colormap = (Colormap)colormap;
51 attr.event_mask = KeyPressMask |
52 KeyReleaseMask |
53 ButtonPressMask |
54 ButtonReleaseMask |
55 EnterWindowMask |
56 LeaveWindowMask |
57 PointerMotionMask |
58 ExposureMask |
59 VisibilityChangeMask |
60 StructureNotifyMask |
61 FocusChangeMask |
62 PropertyChangeMask |
63 ColormapChangeMask;
64 win = XCreateWindow(_ecore_x_disp, parent,
65 x, y, w, h, 0,
66 depth,
67 InputOutput,
68 (Visual *)visual,
69 CWBackingStore |
70 CWOverrideRedirect |
71 (colormap ? CWColormap : 0) |
72 CWBorderPixel |
73 CWBackPixmap |
74 CWSaveUnder |
75 CWDontPropagate |
76 CWEventMask |
77 CWBitGravity |
78 CWWinGravity,
79 &attr);
80 if (_ecore_xlib_sync) ecore_x_sync();
81 if (parent == DefaultRootWindow(_ecore_x_disp))
82 ecore_x_window_defaults_set(win);
83
84 return win;
85 }
86
87 /**
88 * Creates a new window.
89 * @param parent The parent window to use. If @p parent is @c 0, the root
90 * window of the default display is used.
91 * @param x X position.
92 * @param y Y position.
93 * @param w Width.
94 * @param h Height.
95 * @return The new window handle.
96 * @ingroup Ecore_X_Window_Create_Group
97 */
98 EAPI Ecore_X_Window
ecore_x_window_new(Ecore_X_Window parent,int x,int y,int w,int h)99 ecore_x_window_new(Ecore_X_Window parent,
100 int x,
101 int y,
102 int w,
103 int h)
104 {
105 Window win;
106 XSetWindowAttributes attr;
107
108 LOGFN;
109 if (parent == 0)
110 parent = DefaultRootWindow(_ecore_x_disp);
111
112 attr.backing_store = NotUseful;
113 attr.override_redirect = False;
114 attr.border_pixel = 0;
115 attr.background_pixmap = None;
116 attr.bit_gravity = NorthWestGravity;
117 attr.win_gravity = NorthWestGravity;
118 attr.save_under = False;
119 attr.do_not_propagate_mask = NoEventMask;
120 attr.event_mask = KeyPressMask |
121 KeyReleaseMask |
122 ButtonPressMask |
123 ButtonReleaseMask |
124 EnterWindowMask |
125 LeaveWindowMask |
126 PointerMotionMask |
127 ExposureMask |
128 VisibilityChangeMask |
129 StructureNotifyMask |
130 FocusChangeMask |
131 PropertyChangeMask |
132 ColormapChangeMask;
133 win = XCreateWindow(_ecore_x_disp, parent,
134 x, y, w, h, 0,
135 CopyFromParent, /*DefaultDepth(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
136 InputOutput,
137 CopyFromParent, /*DefaultVisual(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
138 CWBackingStore |
139 CWOverrideRedirect |
140 /* CWColormap | */
141 CWBorderPixel |
142 CWBackPixmap |
143 CWSaveUnder |
144 CWDontPropagate |
145 CWEventMask |
146 CWBitGravity |
147 CWWinGravity,
148 &attr);
149 if (_ecore_xlib_sync) ecore_x_sync();
150 if (parent == DefaultRootWindow(_ecore_x_disp))
151 ecore_x_window_defaults_set(win);
152
153 return win;
154 }
155
156 /**
157 * Creates a window with the override redirect attribute set to @c True.
158 * @param parent The parent window to use. If @p parent is @c 0, the root
159 * window of the default display is used.
160 * @param x X position.
161 * @param y Y position.
162 * @param w Width.
163 * @param h Height.
164 * @return The new window handle.
165 * @ingroup Ecore_X_Window_Create_Group
166 */
167 EAPI Ecore_X_Window
ecore_x_window_override_new(Ecore_X_Window parent,int x,int y,int w,int h)168 ecore_x_window_override_new(Ecore_X_Window parent,
169 int x,
170 int y,
171 int w,
172 int h)
173 {
174 Window win;
175 XSetWindowAttributes attr;
176
177 LOGFN;
178 if (parent == 0)
179 parent = DefaultRootWindow(_ecore_x_disp);
180
181 attr.backing_store = NotUseful;
182 attr.override_redirect = True;
183 attr.border_pixel = 0;
184 attr.background_pixmap = None;
185 attr.bit_gravity = NorthWestGravity;
186 attr.win_gravity = NorthWestGravity;
187 attr.save_under = False;
188 attr.do_not_propagate_mask = NoEventMask;
189 attr.event_mask = KeyPressMask |
190 KeyReleaseMask |
191 ButtonPressMask |
192 ButtonReleaseMask |
193 EnterWindowMask |
194 LeaveWindowMask |
195 PointerMotionMask |
196 ExposureMask |
197 VisibilityChangeMask |
198 StructureNotifyMask |
199 FocusChangeMask |
200 PropertyChangeMask |
201 ColormapChangeMask;
202 win = XCreateWindow(_ecore_x_disp, parent,
203 x, y, w, h, 0,
204 CopyFromParent, /*DefaultDepth(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
205 InputOutput,
206 CopyFromParent, /*DefaultVisual(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
207 CWBackingStore |
208 CWOverrideRedirect |
209 /* CWColormap | */
210 CWBorderPixel |
211 CWBackPixmap |
212 CWSaveUnder |
213 CWDontPropagate |
214 CWEventMask |
215 CWBitGravity |
216 CWWinGravity,
217 &attr);
218 if (_ecore_xlib_sync) ecore_x_sync();
219 return win;
220 }
221
222 /**
223 * Creates a new input window.
224 * @param parent The parent window to use. If @p parent is @c 0, the root
225 * window of the default display is used.
226 * @param x X position.
227 * @param y Y position.
228 * @param w Width.
229 * @param h Height.
230 * @return The new window.
231 * @ingroup Ecore_X_Window_Create_Group
232 */
233 EAPI Ecore_X_Window
ecore_x_window_input_new(Ecore_X_Window parent,int x,int y,int w,int h)234 ecore_x_window_input_new(Ecore_X_Window parent,
235 int x,
236 int y,
237 int w,
238 int h)
239 {
240 Window win;
241 XSetWindowAttributes attr;
242
243 LOGFN;
244 if (parent == 0)
245 parent = DefaultRootWindow(_ecore_x_disp);
246
247 attr.override_redirect = True;
248 attr.do_not_propagate_mask = NoEventMask;
249 attr.event_mask = KeyPressMask |
250 KeyReleaseMask |
251 ButtonPressMask |
252 ButtonReleaseMask |
253 EnterWindowMask |
254 LeaveWindowMask |
255 PointerMotionMask |
256 ExposureMask |
257 VisibilityChangeMask |
258 StructureNotifyMask |
259 FocusChangeMask |
260 PropertyChangeMask |
261 ColormapChangeMask;
262 win = XCreateWindow(_ecore_x_disp, parent,
263 x, y, w, h, 0,
264 CopyFromParent,
265 InputOnly,
266 CopyFromParent, /*DefaultVisual(_ecore_x_disp, DefaultScreen(_ecore_x_disp)),*/
267 CWOverrideRedirect |
268 CWDontPropagate |
269 CWEventMask,
270 &attr);
271 if (_ecore_xlib_sync) ecore_x_sync();
272 if (parent == DefaultRootWindow(_ecore_x_disp))
273 {
274 }
275
276 return win;
277 }
278
279 /**
280 * @defgroup Ecore_X_Window_Properties_Group X Window Property Functions
281 * @ingroup Ecore_X_Group
282 *
283 * Functions that set window properties.
284 */
285
286 /**
287 * Sets the default properties for the given window.
288 *
289 * The default properties set for the window are @c WM_CLIENT_MACHINE and
290 * @c _NET_WM_PID.
291 *
292 * @param win The given window.
293 * @ingroup Ecore_X_Window_Properties_Group
294 */
295 EAPI void
ecore_x_window_defaults_set(Ecore_X_Window win)296 ecore_x_window_defaults_set(Ecore_X_Window win)
297 {
298 long pid;
299 char buf[MAXHOSTNAMELEN];
300 char *hostname[1];
301 int argc;
302 char **argv;
303 XTextProperty xprop;
304
305 LOGFN;
306 /*
307 * Set WM_CLIENT_MACHINE.
308 */
309 gethostname(buf, MAXHOSTNAMELEN);
310 buf[MAXHOSTNAMELEN - 1] = '\0';
311 hostname[0] = buf;
312 /* The ecore function uses UTF8 which Xlib may not like (especially
313 * with older clients) */
314 /* ecore_x_window_prop_string_set(win, ECORE_X_ATOM_WM_CLIENT_MACHINE,
315 (char *)buf); */
316 if (XStringListToTextProperty(hostname, 1, &xprop))
317 {
318 XSetWMClientMachine(_ecore_x_disp, win, &xprop);
319 XFree(xprop.value);
320 if (_ecore_xlib_sync) ecore_x_sync();
321 }
322 if (_ecore_xlib_sync) ecore_x_sync();
323 /*
324 * Set _NET_WM_PID
325 */
326 pid = getpid();
327 ecore_x_netwm_pid_set(win, pid);
328
329 ecore_x_netwm_window_type_set(win, ECORE_X_WINDOW_TYPE_NORMAL);
330
331 ecore_app_args_get(&argc, &argv);
332 ecore_x_icccm_command_set(win, argc, argv);
333 }
334
335 EAPI void
ecore_x_window_configure(Ecore_X_Window win,Ecore_X_Window_Configure_Mask mask,int x,int y,int w,int h,int border_width,Ecore_X_Window sibling,int stack_mode)336 ecore_x_window_configure(Ecore_X_Window win,
337 Ecore_X_Window_Configure_Mask mask,
338 int x,
339 int y,
340 int w,
341 int h,
342 int border_width,
343 Ecore_X_Window sibling,
344 int stack_mode)
345 {
346 XWindowChanges xwc;
347
348 if (!win)
349 return;
350
351 LOGFN;
352
353 xwc.x = x;
354 xwc.y = y;
355 xwc.width = w;
356 xwc.height = h;
357 xwc.border_width = border_width;
358 xwc.sibling = sibling;
359 xwc.stack_mode = stack_mode;
360
361 XConfigureWindow(_ecore_x_disp, win, mask, &xwc);
362 if (_ecore_xlib_sync) ecore_x_sync();
363 }
364
365 /**
366 * @defgroup Ecore_X_Window_Destroy_Group X Window Destroy Functions
367 * @ingroup Ecore_X_Group
368 *
369 * Functions to destroy X windows.
370 */
371
372 /**
373 * Deletes the given window.
374 * @param win The given window.
375 * @ingroup Ecore_X_Window_Destroy_Group
376 */
377 EAPI void
ecore_x_window_free(Ecore_X_Window win)378 ecore_x_window_free(Ecore_X_Window win)
379 {
380 /* sorry sir, deleting the root window doesn't sound like
381 * a smart idea.
382 */
383 LOGFN;
384 if (!win) return;
385 XDestroyWindow(_ecore_x_disp, win);
386 if (_ecore_xlib_sync) ecore_x_sync();
387 }
388
389 /**
390 * Set if a window should be ignored.
391 * @param win The given window.
392 * @param ignore if to ignore
393 */
394 EAPI void
ecore_x_window_ignore_set(Ecore_X_Window win,int ignore)395 ecore_x_window_ignore_set(Ecore_X_Window win,
396 int ignore)
397 {
398 int i, j, cnt;
399 Ecore_X_Window *t;
400
401 LOGFN;
402 if (ignore)
403 {
404 if (ignore_list)
405 {
406 for (i = 0; i < ignore_num; i++)
407 {
408 if (win == ignore_list[i])
409 return;
410 }
411 t = realloc(ignore_list, (ignore_num + 1) * sizeof(Ecore_X_Window));
412 if (!t) return;
413 ignore_list = t;
414 ignore_list[ignore_num++] = win;
415 }
416 else
417 {
418 ignore_num = 0;
419 ignore_list = malloc(sizeof(Ecore_X_Window));
420 if (ignore_list)
421 ignore_list[ignore_num++] = win;
422 }
423 }
424 else
425 {
426 if (!ignore_list)
427 return;
428
429 for (cnt = ignore_num, i = 0, j = 0; i < cnt; i++)
430 {
431 if (win != ignore_list[i])
432 ignore_list[j++] = ignore_list[i];
433 else
434 ignore_num--;
435 }
436
437 if (ignore_num <= 0)
438 {
439 free(ignore_list);
440 ignore_list = NULL;
441 return;
442 }
443 t = realloc(ignore_list, ignore_num * sizeof(Ecore_X_Window));
444 if (t) ignore_list = t;
445 }
446 }
447
448 /**
449 * Get the ignore list
450 * @param num number of windows in the list
451 * @return list of windows to ignore
452 */
453 EAPI Ecore_X_Window *
ecore_x_window_ignore_list(int * num)454 ecore_x_window_ignore_list(int *num)
455 {
456 if (num)
457 *num = ignore_num;
458
459 return ignore_list;
460 }
461
462 /**
463 * Sends a delete request to the given window.
464 * @param win The given window.
465 * @ingroup Ecore_X_Window_Destroy_Group
466 */
467 EAPI void
ecore_x_window_delete_request_send(Ecore_X_Window win)468 ecore_x_window_delete_request_send(Ecore_X_Window win)
469 {
470 XEvent xev = { 0 };
471
472 /* sorry sir, deleting the root window doesn't sound like
473 * a smart idea.
474 */
475 if (!win)
476 return;
477
478 LOGFN;
479 xev.xclient.type = ClientMessage;
480 xev.xclient.display = _ecore_x_disp;
481 xev.xclient.window = win;
482 xev.xclient.message_type = ECORE_X_ATOM_WM_PROTOCOLS;
483 xev.xclient.format = 32;
484 xev.xclient.data.l[0] = ECORE_X_ATOM_WM_DELETE_WINDOW;
485 xev.xclient.data.l[1] = CurrentTime;
486
487 XSendEvent(_ecore_x_disp, win, False, NoEventMask, &xev);
488 if (_ecore_xlib_sync) ecore_x_sync();
489 }
490
491 /**
492 * @defgroup Ecore_X_Window_Visibility_Group X Window Visibility Functions
493 * @ingroup Ecore_X_Group
494 *
495 * Functions to access and change the visibility of X windows.
496 */
497
498 /**
499 * Shows a window.
500 *
501 * Synonymous to "mapping" a window in X Window System terminology.
502 *
503 * @param win The window to show.
504 * @ingroup Ecore_X_Window_Visibility
505 */
506 EAPI void
ecore_x_window_show(Ecore_X_Window win)507 ecore_x_window_show(Ecore_X_Window win)
508 {
509 LOGFN;
510 XMapWindow(_ecore_x_disp, win);
511 if (_ecore_xlib_sync) ecore_x_sync();
512 }
513
514 /**
515 * Hides a window.
516 *
517 * Synonymous to "unmapping" a window in X Window System terminology.
518 *
519 * @param win The window to hide.
520 * @ingroup Ecore_X_Window_Visibility
521 */
522 EAPI void
ecore_x_window_hide(Ecore_X_Window win)523 ecore_x_window_hide(Ecore_X_Window win)
524 {
525 XEvent xev = { 0 };
526 Window root;
527 int idum;
528 unsigned int uidum;
529
530 /* ICCCM: SEND unmap event... */
531 LOGFN;
532 root = win;
533 if (ScreenCount(_ecore_x_disp) == 1)
534 root = DefaultRootWindow(_ecore_x_disp);
535 else
536 XGetGeometry(_ecore_x_disp,
537 win,
538 &root,
539 &idum,
540 &idum,
541 &uidum,
542 &uidum,
543 &uidum,
544 &uidum);
545
546 XUnmapWindow(_ecore_x_disp, win);
547 xev.xunmap.type = UnmapNotify;
548 xev.xunmap.serial = 0;
549 xev.xunmap.send_event = True;
550 xev.xunmap.display = _ecore_x_disp;
551 xev.xunmap.event = root;
552 xev.xunmap.window = win;
553 xev.xunmap.from_configure = False;
554 XSendEvent(_ecore_x_disp, xev.xunmap.event, False,
555 SubstructureRedirectMask | SubstructureNotifyMask, &xev);
556 if (_ecore_xlib_sync) ecore_x_sync();
557 }
558
559 /**
560 * @defgroup Ecore_X_Window_Geometry_Group X Window Geometry Functions
561 * @ingroup Ecore_X_Group
562 *
563 * Functions that change or retrieve the geometry of X windows.
564 */
565
566 /**
567 * Moves a window to the position @p x, @p y.
568 *
569 * The position is relative to the upper left hand corner of the
570 * parent window.
571 *
572 * @param win The window to move.
573 * @param x X position.
574 * @param y Y position.
575 * @ingroup Ecore_X_Window_Geometry_Group
576 */
577 EAPI void
ecore_x_window_move(Ecore_X_Window win,int x,int y)578 ecore_x_window_move(Ecore_X_Window win,
579 int x,
580 int y)
581 {
582 LOGFN;
583 XMoveWindow(_ecore_x_disp, win, x, y);
584 if (_ecore_xlib_sync) ecore_x_sync();
585 }
586
587 /**
588 * Resizes a window.
589 * @param win The window to resize.
590 * @param w New width of the window.
591 * @param h New height of the window.
592 * @ingroup Ecore_X_Window_Geometry_Group
593 */
594 EAPI void
ecore_x_window_resize(Ecore_X_Window win,int w,int h)595 ecore_x_window_resize(Ecore_X_Window win,
596 int w,
597 int h)
598 {
599 LOGFN;
600 if (w < 1)
601 w = 1;
602
603 if (h < 1)
604 h = 1;
605
606 XResizeWindow(_ecore_x_disp, win, w, h);
607 if (_ecore_xlib_sync) ecore_x_sync();
608 }
609
610 /**
611 * Moves and resizes a window.
612 * @param win The window to move and resize.
613 * @param x New X position of the window.
614 * @param y New Y position of the window.
615 * @param w New width of the window.
616 * @param h New height of the window.
617 * @ingroup Ecore_X_Window_Geometry_Group
618 */
619 EAPI void
ecore_x_window_move_resize(Ecore_X_Window win,int x,int y,int w,int h)620 ecore_x_window_move_resize(Ecore_X_Window win,
621 int x,
622 int y,
623 int w,
624 int h)
625 {
626 LOGFN;
627 if (w < 1)
628 w = 1;
629
630 if (h < 1)
631 h = 1;
632
633 XMoveResizeWindow(_ecore_x_disp, win, x, y, w, h);
634 if (_ecore_xlib_sync) ecore_x_sync();
635 }
636
637 /**
638 * @defgroup Ecore_X_Window_Focus_Functions X Window Focus Functions
639 * @ingroup Ecore_X_Group
640 *
641 * Functions that give the focus to an X Window.
642 */
643
644 /**
645 * Sets the focus to the window @p win.
646 * @param win The window to focus.
647 * @ingroup Ecore_X_Window_Focus_Functions
648 */
649 EAPI void
ecore_x_window_focus(Ecore_X_Window win)650 ecore_x_window_focus(Ecore_X_Window win)
651 {
652 LOGFN;
653 if (win == 0)
654 win = DefaultRootWindow(_ecore_x_disp); // XSetInputFocus(_ecore_x_disp, win, RevertToNone, CurrentTime);
655
656 // XSetInputFocus(_ecore_x_disp, win, RevertToPointerRoot, CurrentTime);
657 XSetInputFocus(_ecore_x_disp, win, RevertToParent, CurrentTime);
658 if (_ecore_xlib_sync) ecore_x_sync();
659 }
660
661 /**
662 * Sets the focus to the given window at a specific time.
663 * @param win The window to focus.
664 * @param t When to set the focus to the window.
665 * @ingroup Ecore_X_Window_Focus_Functions
666 */
667 EAPI void
ecore_x_window_focus_at_time(Ecore_X_Window win,Ecore_X_Time t)668 ecore_x_window_focus_at_time(Ecore_X_Window win,
669 Ecore_X_Time t)
670 {
671 LOGFN;
672 if (win == 0)
673 win = DefaultRootWindow(_ecore_x_disp); // XSetInputFocus(_ecore_x_disp, win, RevertToNone, t);
674
675 // XSetInputFocus(_ecore_x_disp, win, PointerRoot, t);
676 XSetInputFocus(_ecore_x_disp, win, RevertToParent, t);
677 if (_ecore_xlib_sync) ecore_x_sync();
678 }
679
680 /**
681 * gets the window that has focus.
682 * @return The window that has focus.
683 * @ingroup Ecore_X_Window_Focus_Functions
684 */
685 EAPI Ecore_X_Window
ecore_x_window_focus_get(void)686 ecore_x_window_focus_get(void)
687 {
688 Window win;
689 int revert_mode;
690
691 LOGFN;
692 win = 0;
693 XGetInputFocus(_ecore_x_disp, &win, &revert_mode);
694 return win;
695 }
696
697 /**
698 * @defgroup Ecore_X_Window_Z_Order_Group X Window Z Order Functions
699 * @ingroup Ecore_X_Group
700 *
701 * Functions that change the Z order of X windows.
702 */
703
704 /**
705 * Raises the given window.
706 * @param win The window to raise.
707 * @ingroup Ecore_X_Window_Z_Order_Group
708 */
709 EAPI void
ecore_x_window_raise(Ecore_X_Window win)710 ecore_x_window_raise(Ecore_X_Window win)
711 {
712 LOGFN;
713 XRaiseWindow(_ecore_x_disp, win);
714 if (_ecore_xlib_sync) ecore_x_sync();
715 }
716
717 /**
718 * Lowers the given window.
719 * @param win The window to lower.
720 * @ingroup Ecore_X_Window_Z_Order_Group
721 */
722 EAPI void
ecore_x_window_lower(Ecore_X_Window win)723 ecore_x_window_lower(Ecore_X_Window win)
724 {
725 LOGFN;
726 XLowerWindow(_ecore_x_disp, win);
727 if (_ecore_xlib_sync) ecore_x_sync();
728 }
729
730 /**
731 * @defgroup Ecore_X_Window_Parent_Group X Window Parent Functions
732 * @ingroup Ecore_X_Group
733 *
734 * Functions that retrieve or changes the parent window of a window.
735 */
736
737 /**
738 * Moves a window to within another window at a given position.
739 * @param win The window to reparent.
740 * @param new_parent The new parent window.
741 * @param x X position within new parent window.
742 * @param y Y position within new parent window.
743 * @ingroup Ecore_X_Window_Parent_Group
744 */
745 EAPI void
ecore_x_window_reparent(Ecore_X_Window win,Ecore_X_Window new_parent,int x,int y)746 ecore_x_window_reparent(Ecore_X_Window win,
747 Ecore_X_Window new_parent,
748 int x,
749 int y)
750 {
751 LOGFN;
752 if (new_parent == 0)
753 new_parent = DefaultRootWindow(_ecore_x_disp);
754
755 XReparentWindow(_ecore_x_disp, win, new_parent, x, y);
756 if (_ecore_xlib_sync) ecore_x_sync();
757 }
758
759 /**
760 * Retrieves the size of the given window.
761 * @param win The given window.
762 * @param w Pointer to an integer into which the width is to be stored.
763 * @param h Pointer to an integer into which the height is to be stored.
764 * @ingroup Ecore_X_Window_Geometry_Group
765 */
766 EAPI void
ecore_x_window_size_get(Ecore_X_Window win,int * w,int * h)767 ecore_x_window_size_get(Ecore_X_Window win,
768 int *w,
769 int *h)
770 {
771 int dummy_x, dummy_y;
772
773 LOGFN;
774 if (win == 0)
775 win = DefaultRootWindow(_ecore_x_disp);
776
777 ecore_x_drawable_geometry_get(win, &dummy_x, &dummy_y, w, h);
778 if (_ecore_xlib_sync) ecore_x_sync();
779 }
780
781 /**
782 * Retrieves the geometry of the given window.
783 *
784 * Note that the x & y coordinates are relative to your parent. In
785 * particular for reparenting window managers - relative to you window border.
786 * If you want screen coordinates either walk the window tree to the root,
787 * else for ecore_evas applications see ecore_evas_geometry_get(). Elementary
788 * applications can use elm_win_screen_position_get().
789 *
790 * @param win The given window.
791 * @param x Pointer to an integer in which the X position is to be stored.
792 * @param y Pointer to an integer in which the Y position is to be stored.
793 * @param w Pointer to an integer in which the width is to be stored.
794 * @param h Pointer to an integer in which the height is to be stored.
795 * @ingroup Ecore_X_Window_Geometry_Group
796 */
797 EAPI void
ecore_x_window_geometry_get(Ecore_X_Window win,int * x,int * y,int * w,int * h)798 ecore_x_window_geometry_get(Ecore_X_Window win,
799 int *x,
800 int *y,
801 int *w,
802 int *h)
803 {
804 LOGFN;
805 if (!win)
806 win = DefaultRootWindow(_ecore_x_disp);
807
808 ecore_x_drawable_geometry_get(win, x, y, w, h);
809 if (_ecore_xlib_sync) ecore_x_sync();
810 }
811
812 /**
813 * Retrieves the width of the border of the given window.
814 * @param win The given window.
815 * @return Width of the border of @p win.
816 * @ingroup Ecore_X_Window_Geometry_Group
817 */
818 EAPI int
ecore_x_window_border_width_get(Ecore_X_Window win)819 ecore_x_window_border_width_get(Ecore_X_Window win)
820 {
821 int w;
822 LOGFN;
823 /* doesn't make sense to call this on a root window */
824 if (!win)
825 return 0;
826
827 w = ecore_x_drawable_border_width_get(win);
828 if (_ecore_xlib_sync) ecore_x_sync();
829 return w;
830 }
831
832 /**
833 * Sets the width of the border of the given window.
834 * @param win The given window.
835 * @param width The new border width.
836 * @ingroup Ecore_X_Window_Geometry_Group
837 */
838 EAPI void
ecore_x_window_border_width_set(Ecore_X_Window win,int width)839 ecore_x_window_border_width_set(Ecore_X_Window win,
840 int width)
841 {
842 LOGFN;
843 /* doesn't make sense to call this on a root window */
844 if (!win)
845 return;
846
847 XSetWindowBorderWidth (_ecore_x_disp, win, width);
848 if (_ecore_xlib_sync) ecore_x_sync();
849 }
850
851 /**
852 * Retrieves the depth of the given window.
853 * @param win The given window.
854 * @return Depth of the window.
855 */
856 EAPI int
ecore_x_window_depth_get(Ecore_X_Window win)857 ecore_x_window_depth_get(Ecore_X_Window win)
858 {
859 int d;
860 LOGFN;
861 d = ecore_x_drawable_depth_get(win);
862 if (_ecore_xlib_sync) ecore_x_sync();
863 return d;
864 }
865
866 /**
867 * @brief Show the cursor on a window of type Ecore_X_Window.
868 * @param win The window for which the cursor will be showed.
869 * @param show Enables the show of the cursor on the window if equals EINA_TRUE, disables if equals EINA_FALSE.
870 */
871 EAPI void
ecore_x_window_cursor_show(Ecore_X_Window win,Eina_Bool show)872 ecore_x_window_cursor_show(Ecore_X_Window win,
873 Eina_Bool show)
874 {
875 LOGFN;
876 if (win == 0)
877 win = DefaultRootWindow(_ecore_x_disp);
878
879 if (!show)
880 {
881 Cursor c;
882 XColor cl;
883 Pixmap p, m;
884 GC gc;
885 XGCValues gcv;
886
887 p = XCreatePixmap(_ecore_x_disp, win, 1, 1, 1);
888 if (_ecore_xlib_sync) ecore_x_sync();
889 m = XCreatePixmap(_ecore_x_disp, win, 1, 1, 1);
890 if (_ecore_xlib_sync) ecore_x_sync();
891 gc = XCreateGC(_ecore_x_disp, m, 0, &gcv);
892 if (_ecore_xlib_sync) ecore_x_sync();
893 XSetForeground(_ecore_x_disp, gc, 0);
894 if (_ecore_xlib_sync) ecore_x_sync();
895 XDrawPoint(_ecore_x_disp, m, gc, 0, 0);
896 if (_ecore_xlib_sync) ecore_x_sync();
897 XFreeGC(_ecore_x_disp, gc);
898 c = XCreatePixmapCursor(_ecore_x_disp, p, m, &cl, &cl, 0, 0);
899 if (_ecore_xlib_sync) ecore_x_sync();
900 XDefineCursor(_ecore_x_disp, win, c);
901 XFreeCursor(_ecore_x_disp, c);
902 XFreePixmap(_ecore_x_disp, p);
903 XFreePixmap(_ecore_x_disp, m);
904 }
905 else
906 XDefineCursor(_ecore_x_disp, win, 0);
907 if (_ecore_xlib_sync) ecore_x_sync();
908 }
909
910 EAPI void
ecore_x_window_cursor_set(Ecore_X_Window win,Ecore_X_Cursor c)911 ecore_x_window_cursor_set(Ecore_X_Window win,
912 Ecore_X_Cursor c)
913 {
914 #ifdef ECORE_XI2
915 int devid;
916 #endif
917
918 LOGFN;
919 #ifdef ECORE_XI2
920 XIGetClientPointer(_ecore_x_disp, None, &devid);
921 if (c == 0)
922 XIUndefineCursor(_ecore_x_disp, devid, win);
923 else
924 XIDefineCursor(_ecore_x_disp, devid, win, c);
925 #else
926 if (c == 0)
927 XUndefineCursor(_ecore_x_disp, win);
928 else
929 XDefineCursor(_ecore_x_disp, win, c);
930 #endif
931 if (_ecore_xlib_sync) ecore_x_sync();
932 }
933
934 /**
935 * Finds out whether the given window is currently visible.
936 * @param win The given window.
937 * @return 1 if the window is visible, otherwise 0.
938 * @ingroup Ecore_X_Window_Visibility_Group
939 */
940 EAPI int
ecore_x_window_visible_get(Ecore_X_Window win)941 ecore_x_window_visible_get(Ecore_X_Window win)
942 {
943 Eina_Bool ret;
944 XWindowAttributes attr;
945
946 LOGFN;
947 ret = (XGetWindowAttributes(_ecore_x_disp, win, &attr) &&
948 (attr.map_state == IsViewable));
949 if (_ecore_xlib_sync) ecore_x_sync();
950 return ret;
951 }
952
953 typedef struct _Shadow Shadow;
954 struct _Shadow
955 {
956 Shadow *parent;
957 Shadow **children;
958 Window win;
959 int children_num;
960 short x, y;
961 unsigned short w, h;
962 };
963
964 static Shadow **shadow_base = NULL;
965 static int shadow_num = 0;
966
967 static Shadow *
_ecore_x_window_tree_walk(Window win)968 _ecore_x_window_tree_walk(Window win)
969 {
970 Window *list = NULL;
971 Window parent_win = 0, root_win = 0;
972 unsigned int num;
973 Shadow *s, **sl;
974 XWindowAttributes att;
975 Eina_Bool ret;
976
977 ret = (XGetWindowAttributes(_ecore_x_disp, win, &att) && (att.map_state == IsViewable));
978 if (_ecore_xlib_sync) ecore_x_sync();
979 if (!ret) return NULL; // if (att.class == InputOnly) return NULL;
980
981 s = calloc(1, sizeof(Shadow));
982 if (!s)
983 return NULL;
984
985 s->win = win;
986 s->x = att.x;
987 s->y = att.y;
988 s->w = att.width;
989 s->h = att.height;
990 if (XQueryTree(_ecore_x_disp, s->win, &root_win, &parent_win,
991 &list, &num))
992 {
993 if (_ecore_xlib_sync) ecore_x_sync();
994 s->children = calloc(1, sizeof(Shadow *) * num);
995 if (s->children)
996 {
997 size_t i, j;
998 s->children_num = num;
999 for (i = 0; i < num; i++)
1000 {
1001 s->children[i] = _ecore_x_window_tree_walk(list[i]);
1002 if (s->children[i])
1003 s->children[i]->parent = s;
1004 }
1005 /* compress list down */
1006 j = 0;
1007 for (i = 0; i < num; i++)
1008 {
1009 if (s->children[i])
1010 {
1011 s->children[j] = s->children[i];
1012 j++;
1013 }
1014 }
1015 if (j == 0)
1016 {
1017 free(s->children);
1018 s->children = NULL;
1019 s->children_num = 0;
1020 }
1021 else
1022 {
1023 s->children_num = j;
1024 sl = realloc(s->children, sizeof(Shadow *) * j);
1025 if (sl)
1026 s->children = sl;
1027 }
1028 }
1029 }
1030
1031 if (list)
1032 XFree(list);
1033
1034 return s;
1035 }
1036
1037 static void
_ecore_x_window_tree_shadow_free1(Shadow * s)1038 _ecore_x_window_tree_shadow_free1(Shadow *s)
1039 {
1040 int i;
1041
1042 if (!s)
1043 return;
1044
1045 if (s->children)
1046 {
1047 for (i = 0; i < s->children_num; i++)
1048 {
1049 if (s->children[i])
1050 _ecore_x_window_tree_shadow_free1(s->children[i]);
1051 }
1052 free(s->children);
1053 }
1054
1055 free(s);
1056 }
1057
1058 static void
_ecore_x_window_tree_shadow_free(void)1059 _ecore_x_window_tree_shadow_free(void)
1060 {
1061 int i;
1062
1063 if (!shadow_base)
1064 return;
1065
1066 for (i = 0; i < shadow_num; i++)
1067 {
1068 if (!shadow_base[i])
1069 continue;
1070
1071 _ecore_x_window_tree_shadow_free1(shadow_base[i]);
1072 }
1073 free(shadow_base);
1074 shadow_base = NULL;
1075 shadow_num = 0;
1076 }
1077
1078 static void
_ecore_x_window_tree_shadow_populate(void)1079 _ecore_x_window_tree_shadow_populate(void)
1080 {
1081 Ecore_X_Window *roots;
1082 int i, num;
1083
1084 roots = ecore_x_window_root_list(&num);
1085 if (roots)
1086 {
1087 shadow_base = calloc(1, sizeof(Shadow *) * num);
1088 if (shadow_base)
1089 {
1090 shadow_num = num;
1091 for (i = 0; i < num; i++)
1092 shadow_base[i] = _ecore_x_window_tree_walk(roots[i]);
1093 }
1094
1095 free(roots);
1096 }
1097 }
1098
1099 /*
1100 static int shadow_count = 0;
1101
1102 static void
1103 _ecore_x_window_tree_shadow_start(void)
1104 {
1105 shadow_count++;
1106 if (shadow_count > 1) return;
1107 _ecore_x_window_tree_shadow_populate();
1108 }
1109
1110 static void
1111 _ecore_x_window_tree_shadow_stop(void)
1112 {
1113 shadow_count--;
1114 if (shadow_count != 0) return;
1115 _ecore_x_window_tree_shadow_free();
1116 }
1117 */
1118
1119 static Shadow *
_ecore_x_window_shadow_tree_find_shadow(Shadow * s,Window win)1120 _ecore_x_window_shadow_tree_find_shadow(Shadow *s,
1121 Window win)
1122 {
1123 Shadow *ss;
1124 int i;
1125
1126 if (s->win == win)
1127 return s;
1128
1129 if (s->children)
1130 for (i = 0; i < s->children_num; i++)
1131 {
1132 if (!s->children[i])
1133 continue;
1134
1135 if ((ss =
1136 _ecore_x_window_shadow_tree_find_shadow(s->children[i], win)))
1137 return ss;
1138 }
1139
1140 return NULL;
1141 }
1142
1143 static Shadow *
_ecore_x_window_shadow_tree_find(Window base)1144 _ecore_x_window_shadow_tree_find(Window base)
1145 {
1146 Shadow *s;
1147 int i;
1148
1149 for (i = 0; i < shadow_num; i++)
1150 {
1151 if (!shadow_base[i])
1152 continue;
1153
1154 if ((s = _ecore_x_window_shadow_tree_find_shadow(shadow_base[i], base)))
1155 return s;
1156 }
1157 return NULL;
1158 }
1159
1160 static int
_inside_rects(Shadow * s,int x,int y,int bx,int by,Ecore_X_Rectangle * rects,int num)1161 _inside_rects(Shadow *s,
1162 int x,
1163 int y,
1164 int bx,
1165 int by,
1166 Ecore_X_Rectangle *rects,
1167 int num)
1168 {
1169 int i, inside;
1170
1171 if (!rects) return 0;
1172 inside = 0;
1173 for (i = 0; i < num; i++)
1174 {
1175 if ((x >= s->x + bx + rects[i].x) &&
1176 (y >= s->y + by + rects[i].y) &&
1177 (x < (int)(s->x + bx + rects[i].x + rects[i].width)) &&
1178 (y < (int)(s->y + by + rects[i].y + rects[i].height)))
1179 {
1180 inside = 1;
1181 break;
1182 }
1183 }
1184 free(rects);
1185 return inside;
1186 }
1187
1188 static Window
_ecore_x_window_shadow_tree_at_xy_get_shadow(Shadow * s,int bx,int by,int x,int y,Ecore_X_Window * skip,int skip_num)1189 _ecore_x_window_shadow_tree_at_xy_get_shadow(Shadow *s,
1190 int bx,
1191 int by,
1192 int x,
1193 int y,
1194 Ecore_X_Window *skip,
1195 int skip_num)
1196 {
1197 Window child;
1198 int i, j;
1199 int wx, wy;
1200
1201 wx = s->x + bx;
1202 wy = s->y + by;
1203 if (!((x >= wx) && (y >= wy) && (x < (wx + s->w)) && (y < (wy + s->h))))
1204 return 0;
1205
1206 /* FIXME: get shape */
1207 {
1208 int num;
1209 Ecore_X_Rectangle *rects;
1210
1211 num = 0;
1212 rects = ecore_x_window_shape_rectangles_get(s->win, &num);
1213 if (!_inside_rects(s, x, y, bx, by, rects, num)) return 0;
1214 num = 0;
1215 rects = ecore_x_window_shape_input_rectangles_get(s->win, &num);
1216 if (!_inside_rects(s, x, y, bx, by, rects, num)) return 0;
1217 }
1218
1219 if (s->children)
1220 {
1221 int skipit = 0;
1222
1223 for (i = s->children_num - 1; i >= 0; --i)
1224 {
1225 if (!s->children[i])
1226 continue;
1227
1228 skipit = 0;
1229 if (skip)
1230 for (j = 0; j < skip_num; j++)
1231 {
1232 if (s->children[i]->win == skip[j])
1233 {
1234 skipit = 1;
1235 goto onward;
1236 }
1237 }
1238
1239 onward:
1240 if (!skipit)
1241 if ((child =
1242 _ecore_x_window_shadow_tree_at_xy_get_shadow(s->
1243 children[i
1244 ], wx, wy,
1245 x, y, skip,
1246 skip_num)))
1247 return child;
1248 }
1249 }
1250
1251 return s->win;
1252 }
1253
1254 static Window
_ecore_x_window_shadow_tree_at_xy_get(Window base,int bx,int by,int x,int y,Ecore_X_Window * skip,int skip_num)1255 _ecore_x_window_shadow_tree_at_xy_get(Window base,
1256 int bx,
1257 int by,
1258 int x,
1259 int y,
1260 Ecore_X_Window *skip,
1261 int skip_num)
1262 {
1263 Shadow *s;
1264
1265 if (!shadow_base)
1266 {
1267 _ecore_x_window_tree_shadow_populate();
1268 if (!shadow_base)
1269 return 0;
1270 }
1271
1272 s = _ecore_x_window_shadow_tree_find(base);
1273 if (!s)
1274 return 0;
1275
1276 return _ecore_x_window_shadow_tree_at_xy_get_shadow(s,
1277 bx,
1278 by,
1279 x,
1280 y,
1281 skip,
1282 skip_num);
1283 }
1284
1285 /**
1286 * Retrieves the top, visible window at the given location,
1287 * but skips the windows in the list. This uses a shadow tree built from the
1288 * window tree that is only updated the first time
1289 * ecore_x_window_shadow_tree_at_xy_with_skip_get() is called, or the next time
1290 * it is called after a ecore_x_window_shadow_tree_flush()
1291 * @param base The base window to start searching from (normally root).
1292 * @param x The given X position.
1293 * @param y The given Y position.
1294 * @param skip The list of windows to be skipped.
1295 * @param skip_num The number of windows to be skipped.
1296 * @return The window at that position.
1297 * @ingroup Ecore_X_Window_Geometry_Group
1298 */
1299 EAPI Ecore_X_Window
ecore_x_window_shadow_tree_at_xy_with_skip_get(Ecore_X_Window base,int x,int y,Ecore_X_Window * skip,int skip_num)1300 ecore_x_window_shadow_tree_at_xy_with_skip_get(Ecore_X_Window base,
1301 int x,
1302 int y,
1303 Ecore_X_Window *skip,
1304 int skip_num)
1305 {
1306 LOGFN;
1307 return _ecore_x_window_shadow_tree_at_xy_get(base,
1308 0,
1309 0,
1310 x,
1311 y,
1312 skip,
1313 skip_num);
1314 }
1315
1316 /**
1317 * Retrieves the parent window a given window has. This uses the shadow window
1318 * tree.
1319 * @param root The root window of @p win - if 0, this will be automatically determined with extra processing overhead
1320 * @param win The window to get the parent window of
1321 * @return The parent window of @p win
1322 * @ingroup Ecore_X_Window_Geometry_Group
1323 */
1324 EAPI Ecore_X_Window
ecore_x_window_shadow_parent_get(Ecore_X_Window root EINA_UNUSED,Ecore_X_Window win)1325 ecore_x_window_shadow_parent_get(Ecore_X_Window root EINA_UNUSED,
1326 Ecore_X_Window win)
1327 {
1328 Shadow *s;
1329 int i;
1330
1331 LOGFN;
1332 if (!shadow_base)
1333 {
1334 _ecore_x_window_tree_shadow_populate();
1335 if (!shadow_base)
1336 return 0;
1337 }
1338
1339 for (i = 0; i < shadow_num; i++)
1340 {
1341 if (!shadow_base[i])
1342 continue;
1343
1344 s = _ecore_x_window_shadow_tree_find_shadow(shadow_base[i], win);
1345 if (s)
1346 {
1347 if (!s->parent)
1348 return 0;
1349
1350 return s->parent->win;
1351 }
1352 }
1353 return 0;
1354 }
1355
1356 /**
1357 * Flushes the window shadow tree so nothing is stored.
1358 * @ingroup Ecore_X_Window_Geometry_Group
1359 */
1360 EAPI void
ecore_x_window_shadow_tree_flush(void)1361 ecore_x_window_shadow_tree_flush(void)
1362 {
1363 LOGFN;
1364 _ecore_x_window_tree_shadow_free();
1365 }
1366
1367 /**
1368 * Retrieves the root window a given window is on.
1369 * @param win The window to get the root window of
1370 * @return The root window of @p win
1371 * @ingroup Ecore_X_Window_Geometry_Group
1372 */
1373 EAPI Ecore_X_Window
ecore_x_window_root_get(Ecore_X_Window win)1374 ecore_x_window_root_get(Ecore_X_Window win)
1375 {
1376 XWindowAttributes att;
1377
1378 LOGFN;
1379 if (!XGetWindowAttributes(_ecore_x_disp, win, &att))
1380 return 0;
1381
1382 return att.root;
1383 }
1384
1385 static Window
_ecore_x_window_at_xy_get(Window base,int bx,int by,int x,int y,Ecore_X_Window * skip,int skip_num)1386 _ecore_x_window_at_xy_get(Window base,
1387 int bx,
1388 int by,
1389 int x,
1390 int y,
1391 Ecore_X_Window *skip,
1392 int skip_num)
1393 {
1394 Window *list = NULL;
1395 Window parent_win = 0, child = 0, root_win = 0;
1396 int i, j, wx, wy, ww, wh;
1397 unsigned int num;
1398
1399 LOGFN;
1400 if (!ecore_x_window_visible_get(base))
1401 return 0;
1402
1403 LOGFN;
1404 ecore_x_window_geometry_get(base, &wx, &wy, &ww, &wh);
1405 wx += bx;
1406 wy += by;
1407
1408 if (!((x >= wx) && (y >= wy) && (x < (wx + ww)) && (y < (wy + wh))))
1409 return 0;
1410
1411 LOGFN;
1412 if (!XQueryTree(_ecore_x_disp, base, &root_win, &parent_win, &list, &num))
1413 return base;
1414
1415 if (list)
1416 {
1417 int skipit = 0;
1418
1419 for (i = num - 1; i >= 0; --i)
1420 {
1421 skipit = 0;
1422
1423 if (skip)
1424 for (j = 0; j < skip_num; j++)
1425 {
1426 if (list[i] == skip[j])
1427 {
1428 skipit = 1;
1429 goto onward;
1430 }
1431 }
1432
1433 onward:
1434 if (!skipit)
1435 if ((child =
1436 _ecore_x_window_at_xy_get(list[i], wx, wy, x, y, skip,
1437 skip_num)))
1438 {
1439 XFree(list);
1440 return child;
1441 }
1442 }
1443 XFree(list);
1444 }
1445
1446 return base;
1447 }
1448
1449 /**
1450 * Retrieves the top, visible window at the given location.
1451 * @param x The given X position.
1452 * @param y The given Y position.
1453 * @return The window at that position.
1454 * @ingroup Ecore_X_Window_Geometry_Group
1455 */
1456 EAPI Ecore_X_Window
ecore_x_window_at_xy_get(int x,int y)1457 ecore_x_window_at_xy_get(int x,
1458 int y)
1459 {
1460 Ecore_X_Window win, root;
1461
1462 LOGFN;
1463 /* FIXME: Proper function to determine current root/virtual root
1464 * window missing here */
1465 root = DefaultRootWindow(_ecore_x_disp);
1466
1467 ecore_x_grab();
1468 win = _ecore_x_window_at_xy_get(root, 0, 0, x, y, NULL, 0);
1469 ecore_x_ungrab();
1470
1471 return win ? win : root;
1472 }
1473
1474 /**
1475 * Retrieves the top, visible window at the given location,
1476 * but skips the windows in the list.
1477 * @param x The given X position.
1478 * @param y The given Y position.
1479 * @param skip The list of windows to be skipped.
1480 * @param skip_num The number of windows to be skipped.
1481 * @return The window at that position.
1482 * @ingroup Ecore_X_Window_Geometry_Group
1483 */
1484 EAPI Ecore_X_Window
ecore_x_window_at_xy_with_skip_get(int x,int y,Ecore_X_Window * skip,int skip_num)1485 ecore_x_window_at_xy_with_skip_get(int x,
1486 int y,
1487 Ecore_X_Window *skip,
1488 int skip_num)
1489 {
1490 Ecore_X_Window win, root;
1491
1492 LOGFN;
1493 /* FIXME: Proper function to determine current root/virtual root
1494 * window missing here */
1495 root = DefaultRootWindow(_ecore_x_disp);
1496
1497 ecore_x_grab();
1498 win = _ecore_x_window_at_xy_get(root, 0, 0, x, y, skip, skip_num);
1499 ecore_x_ungrab();
1500
1501 return win ? win : root;
1502 }
1503
1504 EAPI Ecore_X_Window
ecore_x_window_at_xy_begin_get(Ecore_X_Window begin,int x,int y)1505 ecore_x_window_at_xy_begin_get(Ecore_X_Window begin,
1506 int x,
1507 int y)
1508 {
1509 Ecore_X_Window win;
1510
1511 LOGFN;
1512 ecore_x_grab();
1513 win = _ecore_x_window_at_xy_get(begin, 0, 0, x, y, NULL, 0);
1514 ecore_x_ungrab();
1515
1516 return win ? win : begin;
1517 }
1518
1519 /**
1520 * Retrieves the parent window of the given window.
1521 * @param win The given window.
1522 * @return The parent window of @p win.
1523 * @ingroup Ecore_X_Window_Parent_Group
1524 */
1525 EAPI Ecore_X_Window
ecore_x_window_parent_get(Ecore_X_Window win)1526 ecore_x_window_parent_get(Ecore_X_Window win)
1527 {
1528 Window root, parent, *children = NULL;
1529 unsigned int num;
1530 Eina_Bool success;
1531
1532 LOGFN;
1533 success = XQueryTree(_ecore_x_disp, win, &root, &parent, &children, &num);
1534 if (_ecore_xlib_sync) ecore_x_sync();
1535 if (!success) return 0;
1536
1537 if (children)
1538 XFree(children);
1539
1540 return parent;
1541 }
1542
1543 /**
1544 * Sets the background color of the given window.
1545 * @param win The given window
1546 * @param r red value (0...65536, 16 bits)
1547 * @param g green value (0...65536, 16 bits)
1548 * @param b blue value (0...65536, 16 bits)
1549 */
1550 EAPI void
ecore_x_window_background_color_set(Ecore_X_Window win,unsigned short r,unsigned short g,unsigned short b)1551 ecore_x_window_background_color_set(Ecore_X_Window win,
1552 unsigned short r,
1553 unsigned short g,
1554 unsigned short b)
1555 {
1556 XSetWindowAttributes attr;
1557 Colormap map;
1558 XColor col;
1559
1560 LOGFN;
1561 col.red = r;
1562 col.green = g;
1563 col.blue = b;
1564
1565 map = DefaultColormap(_ecore_x_disp, DefaultScreen(_ecore_x_disp));
1566 XAllocColor(_ecore_x_disp, map, &col);
1567
1568 attr.background_pixel = col.pixel;
1569 XChangeWindowAttributes(_ecore_x_disp, win, CWBackPixel, &attr);
1570 if (_ecore_xlib_sync) ecore_x_sync();
1571 }
1572
1573 EAPI void
ecore_x_window_gravity_set(Ecore_X_Window win,Ecore_X_Gravity grav)1574 ecore_x_window_gravity_set(Ecore_X_Window win,
1575 Ecore_X_Gravity grav)
1576 {
1577 XSetWindowAttributes att;
1578
1579 LOGFN;
1580 att.win_gravity = grav;
1581 XChangeWindowAttributes(_ecore_x_disp, win, CWWinGravity, &att);
1582 if (_ecore_xlib_sync) ecore_x_sync();
1583 }
1584
1585 EAPI void
ecore_x_window_pixel_gravity_set(Ecore_X_Window win,Ecore_X_Gravity grav)1586 ecore_x_window_pixel_gravity_set(Ecore_X_Window win,
1587 Ecore_X_Gravity grav)
1588 {
1589 XSetWindowAttributes att;
1590
1591 LOGFN;
1592 att.bit_gravity = grav;
1593 XChangeWindowAttributes(_ecore_x_disp, win, CWBitGravity, &att);
1594 if (_ecore_xlib_sync) ecore_x_sync();
1595 }
1596
1597 EAPI void
ecore_x_window_pixmap_set(Ecore_X_Window win,Ecore_X_Pixmap pmap)1598 ecore_x_window_pixmap_set(Ecore_X_Window win,
1599 Ecore_X_Pixmap pmap)
1600 {
1601 LOGFN;
1602 XSetWindowBackgroundPixmap(_ecore_x_disp, win, pmap);
1603 if (_ecore_xlib_sync) ecore_x_sync();
1604 }
1605
1606 EAPI void
ecore_x_window_area_clear(Ecore_X_Window win,int x,int y,int w,int h)1607 ecore_x_window_area_clear(Ecore_X_Window win,
1608 int x,
1609 int y,
1610 int w,
1611 int h)
1612 {
1613 LOGFN;
1614 XClearArea(_ecore_x_disp, win, x, y, w, h, False);
1615 if (_ecore_xlib_sync) ecore_x_sync();
1616 }
1617
1618 EAPI void
ecore_x_window_area_expose(Ecore_X_Window win,int x,int y,int w,int h)1619 ecore_x_window_area_expose(Ecore_X_Window win,
1620 int x,
1621 int y,
1622 int w,
1623 int h)
1624 {
1625 LOGFN;
1626 XClearArea(_ecore_x_disp, win, x, y, w, h, True);
1627 if (_ecore_xlib_sync) ecore_x_sync();
1628 }
1629
1630 EAPI void
ecore_x_window_override_set(Ecore_X_Window win,Eina_Bool override)1631 ecore_x_window_override_set(Ecore_X_Window win,
1632 Eina_Bool override)
1633 {
1634 XSetWindowAttributes att;
1635
1636 LOGFN;
1637 att.override_redirect = override;
1638 XChangeWindowAttributes(_ecore_x_disp, win, CWOverrideRedirect, &att);
1639 if (_ecore_xlib_sync) ecore_x_sync();
1640 }
1641
1642 #ifdef ECORE_XRENDER
1643 static Ecore_X_Window
_ecore_x_window_argb_internal_new(Ecore_X_Window parent,int x,int y,int w,int h,Eina_Bool override,Eina_Bool saveunder)1644 _ecore_x_window_argb_internal_new(Ecore_X_Window parent,
1645 int x,
1646 int y,
1647 int w,
1648 int h,
1649 Eina_Bool override,
1650 Eina_Bool saveunder)
1651 {
1652 Window win;
1653 XSetWindowAttributes attr;
1654 XWindowAttributes att;
1655 XVisualInfo *xvi;
1656 XVisualInfo vi_in;
1657 int nvi, i, scr = 0;
1658 XRenderPictFormat *fmt;
1659 Visual *vis;
1660
1661 if (parent == 0)
1662 {
1663 parent = DefaultRootWindow(_ecore_x_disp);
1664 scr = DefaultScreen(_ecore_x_disp);
1665 }
1666 else
1667 {
1668 /* ewww - round trip */
1669 if (XGetWindowAttributes(_ecore_x_disp, parent, &att))
1670 {
1671 if (_ecore_xlib_sync) ecore_x_sync();
1672 for (i = 0; i < ScreenCount(_ecore_x_disp); i++)
1673 {
1674 if (att.screen == ScreenOfDisplay(_ecore_x_disp, i))
1675 {
1676 scr = i;
1677 break;
1678 }
1679 }
1680 }
1681 }
1682
1683 vi_in.screen = scr;
1684 vi_in.depth = 32;
1685 vi_in.class = TrueColor;
1686 xvi = XGetVisualInfo(_ecore_x_disp,
1687 VisualScreenMask |
1688 VisualDepthMask |
1689 VisualClassMask,
1690 &vi_in,
1691 &nvi);
1692 if (_ecore_xlib_sync) ecore_x_sync();
1693 if (!xvi)
1694 return 0;
1695
1696 vis = NULL;
1697 for (i = 0; i < nvi; i++)
1698 {
1699 fmt = XRenderFindVisualFormat(_ecore_x_disp, xvi[i].visual);
1700 if (_ecore_xlib_sync) ecore_x_sync();
1701 if ((fmt->type == PictTypeDirect) && (fmt->direct.alphaMask))
1702 {
1703 vis = xvi[i].visual;
1704 break;
1705 }
1706 }
1707 XFree (xvi);
1708
1709 attr.backing_store = NotUseful;
1710 attr.override_redirect = override;
1711 attr.colormap = XCreateColormap(_ecore_x_disp, parent,
1712 vis, AllocNone);
1713 attr.border_pixel = 0;
1714 attr.background_pixmap = None;
1715 attr.bit_gravity = NorthWestGravity;
1716 attr.win_gravity = NorthWestGravity;
1717 attr.save_under = saveunder;
1718 attr.do_not_propagate_mask = NoEventMask;
1719 attr.event_mask = KeyPressMask |
1720 KeyReleaseMask |
1721 ButtonPressMask |
1722 ButtonReleaseMask |
1723 EnterWindowMask |
1724 LeaveWindowMask |
1725 PointerMotionMask |
1726 ExposureMask |
1727 VisibilityChangeMask |
1728 StructureNotifyMask |
1729 FocusChangeMask |
1730 PropertyChangeMask |
1731 ColormapChangeMask;
1732 win = XCreateWindow(_ecore_x_disp, parent,
1733 x, y, w, h, 0,
1734 32,
1735 InputOutput,
1736 vis,
1737 CWBackingStore |
1738 CWOverrideRedirect |
1739 CWColormap |
1740 CWBorderPixel |
1741 CWBackPixmap |
1742 CWSaveUnder |
1743 CWDontPropagate |
1744 CWEventMask |
1745 CWBitGravity |
1746 CWWinGravity,
1747 &attr);
1748 if (_ecore_xlib_sync) ecore_x_sync();
1749
1750 if (parent == DefaultRootWindow(_ecore_x_disp))
1751 ecore_x_window_defaults_set(win);
1752
1753 return win;
1754 }
1755
1756 #endif /* ifdef ECORE_XRENDER */
1757
1758 EAPI int
ecore_x_window_argb_get(Ecore_X_Window win)1759 ecore_x_window_argb_get(Ecore_X_Window win)
1760 {
1761 #ifdef ECORE_XRENDER
1762 XWindowAttributes att;
1763 XRenderPictFormat *fmt;
1764 Eina_Bool ret;
1765
1766 att.visual = 0;
1767 ret = XGetWindowAttributes(_ecore_x_disp, win, &att);
1768 if (_ecore_xlib_sync) ecore_x_sync();
1769 if (!ret) return 0;
1770
1771 fmt = XRenderFindVisualFormat(_ecore_x_disp, att.visual);
1772 if (_ecore_xlib_sync) ecore_x_sync();
1773 if (!fmt)
1774 return 0;
1775
1776 if ((fmt->type == PictTypeDirect) && (fmt->direct.alphaMask))
1777 return 1;
1778
1779 return 0;
1780 #else /* ifdef ECORE_XRENDER */
1781 return 0;
1782 #endif /* ifdef ECORE_XRENDER */
1783 }
1784
1785 /**
1786 * Creates a new window.
1787 * @param parent The parent window to use. If @p parent is @c 0, the root
1788 * window of the default display is used.
1789 * @param x X position.
1790 * @param y Y position.
1791 * @param w Width.
1792 * @param h Height.
1793 * @return The new window handle.
1794 * @ingroup Ecore_X_Window_Create_Group
1795 */
1796 EAPI Ecore_X_Window
ecore_x_window_manager_argb_new(Ecore_X_Window parent,int x,int y,int w,int h)1797 ecore_x_window_manager_argb_new(Ecore_X_Window parent,
1798 int x,
1799 int y,
1800 int w,
1801 int h)
1802 {
1803 #ifdef ECORE_XRENDER
1804 LOGFN;
1805 return _ecore_x_window_argb_internal_new(parent, x, y, w, h, 1, 0);
1806 #else /* ifdef ECORE_XRENDER */
1807 return 0;
1808 #endif /* ifdef ECORE_XRENDER */
1809 }
1810
1811 /**
1812 * Creates a new window.
1813 * @param parent The parent window to use. If @p parent is @c 0, the root
1814 * window of the default display is used.
1815 * @param x X position.
1816 * @param y Y position.
1817 * @param w Width.
1818 * @param h Height.
1819 * @return The new window handle.
1820 * @ingroup Ecore_X_Window_Create_Group
1821 */
1822 EAPI Ecore_X_Window
ecore_x_window_argb_new(Ecore_X_Window parent,int x,int y,int w,int h)1823 ecore_x_window_argb_new(Ecore_X_Window parent,
1824 int x,
1825 int y,
1826 int w,
1827 int h)
1828 {
1829 #ifdef ECORE_XRENDER
1830 LOGFN;
1831 return _ecore_x_window_argb_internal_new(parent, x, y, w, h, 0, 0);
1832 #else /* ifdef ECORE_XRENDER */
1833 return 0;
1834 #endif /* ifdef ECORE_XRENDER */
1835 }
1836
1837 /**
1838 * Creates a window with the override redirect attribute set to @c True.
1839 * @param parent The parent window to use. If @p parent is @c 0, the root
1840 * window of the default display is used.
1841 * @param x X position.
1842 * @param y Y position.
1843 * @param w Width.
1844 * @param h Height.
1845 * @return The new window handle.
1846 * @ingroup Ecore_X_Window_Create_Group
1847 */
1848 EAPI Ecore_X_Window
ecore_x_window_override_argb_new(Ecore_X_Window parent,int x,int y,int w,int h)1849 ecore_x_window_override_argb_new(Ecore_X_Window parent,
1850 int x,
1851 int y,
1852 int w,
1853 int h)
1854 {
1855 #ifdef ECORE_XRENDER
1856 LOGFN;
1857 return _ecore_x_window_argb_internal_new(parent, x, y, w, h, 1, 0);
1858 #else /* ifdef ECORE_XRENDER */
1859 return 0;
1860 #endif /* ifdef ECORE_XRENDER */
1861 }
1862
1863 EAPI Ecore_X_Window
ecore_x_window_permanent_new(Ecore_X_Window parent,Ecore_X_Atom unique_atom)1864 ecore_x_window_permanent_new(Ecore_X_Window parent, Ecore_X_Atom unique_atom)
1865 {
1866 Display *disp;
1867 Window win, win2, realwin = 0;
1868 Atom type_ret;
1869 int format_ret;
1870 unsigned long ldata, bytes_after, num_ret, *datap;
1871 unsigned char *prop_ret;
1872
1873 LOGFN;
1874 disp = XOpenDisplay(DisplayString(_ecore_x_disp));
1875 if (!disp) return 0;
1876
1877 XGrabServer(disp);
1878 if (XGetWindowProperty(disp, parent, unique_atom, 0, 0x7fffffff,
1879 False, XA_WINDOW, &type_ret, &format_ret,
1880 &num_ret, &bytes_after, &prop_ret) == Success)
1881 {
1882 if (prop_ret)
1883 {
1884 if ((format_ret == 32) && (type_ret == XA_WINDOW) &&
1885 (num_ret == 1))
1886 {
1887 datap = (unsigned long *)prop_ret;
1888 win = (Window)(*datap);
1889 XFree(prop_ret);
1890 if (XGetWindowProperty(disp, win, unique_atom, 0, 0x7fffffff,
1891 False, XA_WINDOW, &type_ret, &format_ret,
1892 &num_ret, &bytes_after, &prop_ret) == Success)
1893 {
1894 if (prop_ret)
1895 {
1896 if ((format_ret == 32) && (type_ret == XA_WINDOW) &&
1897 (num_ret == 1))
1898 {
1899 datap = (unsigned long *)prop_ret;
1900 win2 = (Window)(*datap);
1901 XFree(prop_ret);
1902 if (win2 == win) realwin = win;
1903 }
1904 else XFree(prop_ret);
1905 }
1906 }
1907 }
1908 else XFree(prop_ret);
1909 }
1910 }
1911 if (realwin != 0)
1912 {
1913 XUngrabServer(disp);
1914 XFlush(disp);
1915 XCloseDisplay(disp);
1916 return realwin;
1917 }
1918 win = XCreateSimpleWindow(disp, parent, -77, -77, 7, 7, 0, 0, 0);
1919 ldata = (unsigned long)win;
1920 XChangeProperty(disp, win, unique_atom, XA_WINDOW, 32,
1921 PropModeReplace, (unsigned char *)(&ldata), 1);
1922 XChangeProperty(disp, parent, unique_atom, XA_WINDOW, 32,
1923 PropModeReplace, (unsigned char *)(&ldata), 1);
1924 XSetCloseDownMode(disp, RetainPermanent);
1925 XUngrabServer(disp);
1926 XFlush(disp);
1927 XCloseDisplay(disp);
1928 return win;
1929 }
1930