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