aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_evas/ecore_evas_x.c
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-01-04 18:41:13 +1000
committerDavid Walter Seikel2012-01-04 18:41:13 +1000
commitdd7595a3475407a7fa96a97393bae8c5220e8762 (patch)
treee341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/ecore/src/lib/ecore_evas/ecore_evas_x.c
parentAdd the skeleton. (diff)
downloadSledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2
SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to 'libraries/ecore/src/lib/ecore_evas/ecore_evas_x.c')
-rw-r--r--libraries/ecore/src/lib/ecore_evas/ecore_evas_x.c4289
1 files changed, 4289 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_evas/ecore_evas_x.c b/libraries/ecore/src/lib/ecore_evas/ecore_evas_x.c
new file mode 100644
index 0000000..d9ccd6e
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_evas/ecore_evas_x.c
@@ -0,0 +1,4289 @@
1#include <string.h>
2#include "ecore_evas_private.h"
3#include "Ecore_Evas.h"
4
5#ifdef BUILD_ECORE_EVAS_X11
6static int _ecore_evas_init_count = 0;
7
8static Ecore_Event_Handler *ecore_evas_event_handlers[13];
9
10static int leader_ref = 0;
11static Ecore_X_Window leader_win = 0;
12
13static void
14_ecore_evas_x_group_leader_set(Ecore_Evas *ee)
15{
16 leader_ref++;
17 if (leader_ref == 1)
18 {
19 char *id = NULL;
20
21 leader_win =
22 ecore_x_window_override_new(ee->engine.x.win_root, 1234, 5678, 1, 2);
23 ecore_x_window_defaults_set(leader_win);
24 if ((id = getenv("DESKTOP_STARTUP_ID")))
25 ecore_x_netwm_startup_id_set(leader_win,id);
26 ecore_x_icccm_client_leader_set(leader_win, leader_win);
27 }
28 ee->engine.x.leader = leader_win;
29 ecore_x_icccm_client_leader_set(ee->prop.window, leader_win);
30}
31
32static void
33_ecore_evas_x_group_leader_unset(Ecore_Evas *ee)
34{
35 ecore_x_window_prop_property_del(ee->prop.window,
36 ECORE_X_ATOM_WM_CLIENT_LEADER);
37 if (ee->engine.x.leader == leader_win)
38 {
39 leader_ref--;
40 if (leader_ref <= 0)
41 {
42 ecore_x_window_free(leader_win);
43 leader_win = 0;
44 }
45 ee->engine.x.leader = 0;
46 }
47}
48
49static void
50_ecore_evas_x_group_leader_update(Ecore_Evas *ee)
51{
52 if (ee->engine.x.leader)
53 ecore_x_icccm_client_leader_set(ee->prop.window, ee->engine.x.leader);
54}
55
56static void
57_ecore_evas_x_protocols_set(Ecore_Evas *ee)
58{
59 Ecore_X_Atom protos[3];
60 unsigned int num = 0, tmp = 0;
61
62 if (ee->func.fn_delete_request)
63 protos[num++] = ECORE_X_ATOM_WM_DELETE_WINDOW;
64 protos[num++] = ECORE_X_ATOM_NET_WM_PING;
65 protos[num++] = ECORE_X_ATOM_NET_WM_SYNC_REQUEST;
66 ecore_x_icccm_protocol_atoms_set(ee->prop.window, protos, num);
67
68 if (!ee->engine.x.netwm_sync_counter)
69 ee->engine.x.netwm_sync_counter = ecore_x_sync_counter_new(0);
70
71 tmp = ee->engine.x.netwm_sync_counter;
72 ecore_x_window_prop_card32_set(ee->prop.window,
73 ECORE_X_ATOM_NET_WM_SYNC_REQUEST_COUNTER,
74 &tmp, 1);
75}
76
77static void
78_ecore_evas_x_sync_set(Ecore_Evas *ee)
79{
80 if (((ee->should_be_visible) || (ee->visible)) &&
81 ((ecore_x_e_comp_sync_supported_get(ee->engine.x.win_root)) &&
82 (!ee->no_comp_sync) && (_ecore_evas_app_comp_sync)))
83 {
84 if (!ee->engine.x.sync_counter)
85 ee->engine.x.sync_counter = ecore_x_sync_counter_new(0);
86 }
87 else
88 {
89 if (ee->engine.x.sync_counter)
90 ecore_x_sync_counter_free(ee->engine.x.sync_counter);
91 ee->engine.x.sync_counter = 0;
92 }
93 ecore_x_e_comp_sync_counter_set(ee->prop.window, ee->engine.x.sync_counter);
94}
95
96static void
97_ecore_evas_x_sync_clear(Ecore_Evas *ee)
98{
99 if (!ee->engine.x.sync_counter) return;
100 ecore_x_sync_counter_free(ee->engine.x.sync_counter);
101 ee->engine.x.sync_counter = 0;
102}
103
104# ifdef BUILD_ECORE_EVAS_OPENGL_X11
105static Ecore_X_Window
106_ecore_evas_x_gl_window_new(Ecore_Evas *ee, Ecore_X_Window parent, int x, int y, int w, int h, int override, int argb, const int *opt)
107{
108 Evas_Engine_Info_GL_X11 *einfo;
109 Ecore_X_Window win;
110
111 einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
112 if (einfo)
113 {
114 int screen;
115
116 if (opt)
117 {
118 int op;
119
120 for (op = 0; opt[op]; op++)
121 {
122 if (opt[op] == ECORE_EVAS_GL_X11_OPT_INDIRECT)
123 {
124 op++;
125 einfo->indirect = opt[op];
126 }
127 else if (opt[op] == ECORE_EVAS_GL_X11_OPT_VSYNC)
128 {
129 op++;
130 einfo->vsync = opt[op];
131 }
132 }
133 }
134
135 /* FIXME: this is inefficient as its 1 or more round trips */
136 screen = ecore_x_screen_index_get(ecore_x_default_screen_get());
137 if (ecore_x_screen_count_get() > 1)
138 {
139 Ecore_X_Window *roots;
140 int num, i;
141
142 num = 0;
143 roots = ecore_x_window_root_list(&num);
144 if (roots)
145 {
146 Ecore_X_Window root;
147
148 root = ecore_x_window_root_get(parent);
149 for (i = 0; i < num; i++)
150 {
151 if (root == roots[i])
152 {
153 screen = i;
154 break;
155 }
156 }
157 free(roots);
158 }
159 }
160
161 einfo->info.display = ecore_x_display_get();
162 einfo->info.screen = screen;
163
164 einfo->info.destination_alpha = argb;
165
166 einfo->info.visual = einfo->func.best_visual_get(einfo);
167 einfo->info.colormap = einfo->func.best_colormap_get(einfo);
168 einfo->info.depth = einfo->func.best_depth_get(einfo);
169
170 if ((!einfo->info.visual) ||
171 (!einfo->info.colormap) || (!einfo->info.depth))
172 {
173 WRN("OpenGL X11 init engine '%s' failed - no visual, colormap or depth.", ee->driver);
174 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
175 {
176 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
177 return 0;
178 }
179 }
180
181 if (argb)
182 {
183 if (override)
184 win = ecore_x_window_override_argb_new(parent, x, y, w, h);
185 else
186 win = ecore_x_window_argb_new(parent, x, y, w, h);
187 }
188 else
189 {
190 if (override)
191 win = ecore_x_window_override_new(parent, x, y, w, h);
192 else
193 win = ecore_x_window_new(parent, x, y, w, h);
194 }
195
196 ecore_x_window_pixel_gravity_set(win, ECORE_X_GRAVITY_FORGET);
197
198 /* attr.backing_store = NotUseful; */
199 /* attr.override_redirect = override; */
200 /* attr.colormap = einfo->info.colormap; */
201 /* attr.border_pixel = 0; */
202 /* attr.background_pixmap = None; */
203 /* attr.event_mask = */
204 /* KeyPressMask | KeyReleaseMask | */
205 /* ExposureMask | ButtonPressMask | ButtonReleaseMask | */
206 /* EnterWindowMask | LeaveWindowMask | */
207 /* PointerMotionMask | StructureNotifyMask | VisibilityChangeMask | */
208 /* FocusChangeMask | PropertyChangeMask | ColormapChangeMask; */
209 /* attr.bit_gravity = ForgetGravity; */
210
211 /* win = */
212 /* XCreateWindow(einfo->info.display, parent, x, y, w, h, 0, */
213 /* einfo->info.depth, InputOutput, einfo->info.visual, */
214 /* CWBackingStore | CWColormap | CWBackPixmap | */
215 /* CWBorderPixel | CWBitGravity | CWEventMask | */
216 /* CWOverrideRedirect, &attr); */
217
218 einfo->info.drawable = win;
219
220 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
221 {
222 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
223 ecore_x_window_free(win);
224 return 0;
225 }
226 }
227 else
228 win = 0;
229
230 return win;
231}
232#endif
233
234static int
235_ecore_evas_x_render(Ecore_Evas *ee)
236{
237 int rend = 0;
238 Eina_List *updates = NULL;
239 Eina_List *ll;
240 Ecore_Evas *ee2;
241
242 if ((!ee->no_comp_sync) && (_ecore_evas_app_comp_sync) &&
243 (ee->engine.x.sync_counter) && (!ee->engine.x.sync_began) &&
244 (!ee->engine.x.sync_cancel))
245 return 0;
246
247 EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2)
248 {
249 if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
250 if (ee2->engine.func->fn_render)
251 rend |= ee2->engine.func->fn_render(ee2);
252 if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
253 }
254
255 if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
256 updates = evas_render_updates(ee->evas);
257 if (ee->prop.avoid_damage)
258 {
259 if (ee->engine.x.using_bg_pixmap)
260 {
261 if (updates)
262 {
263 Eina_List *l = NULL;
264 Eina_Rectangle *r;
265
266 EINA_LIST_FOREACH(updates, l, r)
267 ecore_x_window_area_clear(ee->prop.window,
268 r->x, r->y, r->w, r->h);
269 if (ee->shaped)
270 {
271#ifdef EVAS_FRAME_QUEUING
272 evas_sync(ee->evas);
273#endif
274 ecore_x_window_shape_mask_set(ee->prop.window,
275 ee->engine.x.mask);
276 }
277 if (ee->alpha)
278 {
279#ifdef EVAS_FRAME_QUEUING
280 /* wait until ee->engine.x.mask being updated */
281// evas_sync(ee->evas);
282#endif
283// ecore_x_window_shape_input_mask_set(ee->prop.window, ee->engine.x.mask);
284 }
285 evas_render_updates_free(updates);
286 _ecore_evas_idle_timeout_update(ee);
287 rend = 1;
288 }
289 }
290 else
291 {
292 if (updates)
293 {
294 Eina_List *l = NULL;
295 Eina_Rectangle *r;
296
297 EINA_LIST_FOREACH(updates, l, r)
298 {
299 Ecore_X_Rectangle rect;
300 Ecore_X_XRegion *tmpr;
301
302 if (!ee->engine.x.damages)
303 ee->engine.x.damages = ecore_x_xregion_new();
304 tmpr = ecore_x_xregion_new();
305 if (ee->rotation == 0)
306 {
307 rect.x = r->x;
308 rect.y = r->y;
309 rect.width = r->w;
310 rect.height = r->h;
311 }
312 else if (ee->rotation == 90)
313 {
314 rect.x = r->y;
315 rect.y = ee->h - r->x - r->w;
316 rect.width = r->h;
317 rect.height = r->w;
318 }
319 else if (ee->rotation == 180)
320 {
321 rect.x = ee->w - r->x - r->w;
322 rect.y = ee->h - r->y - r->h;
323 rect.width = r->w;
324 rect.height = r->h;
325 }
326 else if (ee->rotation == 270)
327 {
328 rect.x = ee->w - r->y - r->h;
329 rect.y = r->x;
330 rect.width = r->h;
331 rect.height = r->w;
332 }
333 ecore_x_xregion_union_rect(tmpr, ee->engine.x.damages,
334 &rect);
335 ecore_x_xregion_free(ee->engine.x.damages);
336 ee->engine.x.damages = tmpr;
337 }
338 if (ee->engine.x.damages)
339 {
340 /* if we have a damage pixmap - we can avoid exposures by
341 * disabling them just for setting the mask */
342 ecore_x_event_mask_set(ee->prop.window,
343 ECORE_X_EVENT_MASK_KEY_DOWN |
344 ECORE_X_EVENT_MASK_KEY_UP |
345 ECORE_X_EVENT_MASK_MOUSE_DOWN |
346 ECORE_X_EVENT_MASK_MOUSE_UP |
347 ECORE_X_EVENT_MASK_MOUSE_IN |
348 ECORE_X_EVENT_MASK_MOUSE_OUT |
349 ECORE_X_EVENT_MASK_MOUSE_MOVE |
350 // ECORE_X_EVENT_MASK_WINDOW_DAMAGE |
351 ECORE_X_EVENT_MASK_WINDOW_VISIBILITY |
352 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE |
353 ECORE_X_EVENT_MASK_WINDOW_FOCUS_CHANGE |
354 ECORE_X_EVENT_MASK_WINDOW_PROPERTY |
355 ECORE_X_EVENT_MASK_WINDOW_COLORMAP
356 );
357 if (ee->shaped)
358 ecore_x_window_shape_mask_set(ee->prop.window,
359 ee->engine.x.mask);
360 /* and re-enable them again */
361 ecore_x_event_mask_set(ee->prop.window,
362 ECORE_X_EVENT_MASK_KEY_DOWN |
363 ECORE_X_EVENT_MASK_KEY_UP |
364 ECORE_X_EVENT_MASK_MOUSE_DOWN |
365 ECORE_X_EVENT_MASK_MOUSE_UP |
366 ECORE_X_EVENT_MASK_MOUSE_IN |
367 ECORE_X_EVENT_MASK_MOUSE_OUT |
368 ECORE_X_EVENT_MASK_MOUSE_MOVE |
369 ECORE_X_EVENT_MASK_WINDOW_DAMAGE |
370 ECORE_X_EVENT_MASK_WINDOW_VISIBILITY |
371 ECORE_X_EVENT_MASK_WINDOW_CONFIGURE |
372 ECORE_X_EVENT_MASK_WINDOW_FOCUS_CHANGE |
373 ECORE_X_EVENT_MASK_WINDOW_PROPERTY |
374 ECORE_X_EVENT_MASK_WINDOW_COLORMAP
375 );
376 ecore_x_xregion_set(ee->engine.x.damages, ee->engine.x.gc);
377 ecore_x_pixmap_paste(ee->engine.x.pmap, ee->prop.window,
378 ee->engine.x.gc, 0, 0, ee->w, ee->h,
379 0, 0);
380 ecore_x_xregion_free(ee->engine.x.damages);
381 ee->engine.x.damages = NULL;
382 }
383 evas_render_updates_free(updates);
384 _ecore_evas_idle_timeout_update(ee);
385 rend = 1;
386 }
387 }
388 }
389 else if (((ee->visible) && (ee->draw_ok)) ||
390 ((ee->should_be_visible) && (ee->prop.fullscreen)) ||
391 ((ee->should_be_visible) && (ee->prop.override)))
392 {
393 if (updates)
394 {
395 if (ee->shaped)
396 {
397#ifdef EVAS_FRAME_QUEUING
398 evas_sync(ee->evas);
399#endif
400 ecore_x_window_shape_mask_set(ee->prop.window,
401 ee->engine.x.mask);
402 }
403 if (ee->alpha)
404 {
405#ifdef EVAS_FRAME_QUEUING
406 /* wait until ee->engine.x.mask being updated */
407// evas_sync(ee->evas);
408#endif
409// ecore_x_window_shape_input_mask_set(ee->prop.window, ee->engine.x.mask);
410 }
411 evas_render_updates_free(updates);
412 _ecore_evas_idle_timeout_update(ee);
413 rend = 1;
414 }
415 }
416 else
417 evas_norender(ee->evas);
418 if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
419/*
420 if (rend)
421 {
422 static int frames = 0;
423 static double t0 = 0.0;
424 double t, td;
425
426 t = ecore_time_get();
427 frames++;
428 if ((t - t0) > 1.0)
429 {
430 td = t - t0;
431 printf("FPS: %3.3f\n", (double)frames / td);
432 frames = 0;
433 t0 = t;
434 }
435 }
436 */
437
438 return rend;
439}
440
441static void
442_ecore_evas_x_resize_shape(Ecore_Evas *ee)
443{
444 if (!strcmp(ee->driver, "software_x11"))
445 {
446#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
447 Evas_Engine_Info_Software_X11 *einfo;
448
449 einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
450 if (einfo)
451 {
452 unsigned int foreground;
453 Ecore_X_GC gc;
454
455 if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
456 ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
457 foreground = 0;
458 gc = ecore_x_gc_new(ee->engine.x.mask,
459 ECORE_X_GC_VALUE_MASK_FOREGROUND,
460 &foreground);
461 ecore_x_drawable_rectangle_fill(ee->engine.x.mask, gc,
462 0, 0, ee->w, ee->h);
463 ecore_x_gc_free(gc);
464 einfo->info.mask = ee->engine.x.mask;
465 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
466 {
467 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
468 }
469 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
470 }
471#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
472 }
473 else if (!strcmp(ee->driver, "software_16_x11"))
474 {
475#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
476# if 0 /* XXX no shaped window support for software_16_x11 */
477 Evas_Engine_Info_Software_16_X11 *einfo;
478
479 einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
480 if (einfo)
481 {
482 if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
483 ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
484 einfo->info.mask = ee->engine.x.mask;
485 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
486 {
487 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
488 }
489 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
490 }
491# endif /* XXX no shaped window support for software_16_x11 */
492#endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
493 }
494 if (!strcmp(ee->driver, "software_8_x11"))
495 {
496#if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
497 Evas_Engine_Info_Software_8_X11 *einfo;
498
499 einfo = (Evas_Engine_Info_Software_8_X11 *)evas_engine_info_get(ee->evas);
500 if (einfo)
501 {
502 unsigned int foreground;
503 Ecore_X_GC gc;
504
505 if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
506 ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
507 foreground = 0;
508 gc = ecore_x_gc_new(ee->engine.x.mask,
509 ECORE_X_GC_VALUE_MASK_FOREGROUND,
510 &foreground);
511 ecore_x_drawable_rectangle_fill(ee->engine.x.mask, gc,
512 0, 0, ee->w, ee->h);
513 ecore_x_gc_free(gc);
514 einfo->info.mask = ee->engine.x.mask;
515 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
516 {
517 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
518 }
519 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
520 }
521#endif /* BUILD_ECORE_EVAS_SOFTWARE_8_X11 */
522 }
523}
524
525/* TODO: we need to make this work for all the states, not just sticky */
526static Eina_Bool
527_ecore_evas_x_event_property_change(void *data __UNUSED__, int type __UNUSED__, void *event)
528{
529 Ecore_Evas *ee;
530 Ecore_X_Event_Window_Property *e;
531
532 e = event;
533 ee = ecore_event_window_match(e->win);
534 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; /* pass on event */
535 if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
536 if (e->atom == ECORE_X_ATOM_NET_WM_STATE)
537 {
538 unsigned int i, num;
539 Ecore_X_Window_State *state;
540 int sticky = 0;
541
542 /* TODO: we need to move those to the end, with if statements */
543 ee->engine.x.state.modal = 0;
544 ee->engine.x.state.maximized_v = 0;
545 ee->engine.x.state.maximized_h = 0;
546 ee->engine.x.state.shaded = 0;
547 ee->engine.x.state.skip_taskbar = 0;
548 ee->engine.x.state.skip_pager = 0;
549 ee->prop.fullscreen = 0;
550 ee->engine.x.state.fullscreen = 0;
551 ee->engine.x.state.above = 0;
552 ee->engine.x.state.below = 0;
553
554 ecore_x_netwm_window_state_get(e->win, &state, &num);
555 if (state)
556 {
557 for (i = 0; i < num; i++)
558 {
559 switch (state[i])
560 {
561 case ECORE_X_WINDOW_STATE_MODAL:
562 ee->engine.x.state.modal = 1;
563 break;
564 case ECORE_X_WINDOW_STATE_STICKY:
565 if (ee->prop.sticky && ee->engine.x.state.sticky)
566 break;
567
568 sticky = 1;
569 ee->prop.sticky = 1;
570 ee->engine.x.state.sticky = 1;
571 if (ee->func.fn_sticky) ee->func.fn_sticky(ee);
572 break;
573 case ECORE_X_WINDOW_STATE_MAXIMIZED_VERT:
574 ee->engine.x.state.maximized_v = 1;
575 break;
576 case ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ:
577 ee->engine.x.state.maximized_h = 1;
578 break;
579 case ECORE_X_WINDOW_STATE_SHADED:
580 ee->engine.x.state.shaded = 1;
581 break;
582 case ECORE_X_WINDOW_STATE_SKIP_TASKBAR:
583 ee->engine.x.state.skip_taskbar = 1;
584 break;
585 case ECORE_X_WINDOW_STATE_SKIP_PAGER:
586 ee->engine.x.state.skip_pager = 1;
587 break;
588 case ECORE_X_WINDOW_STATE_FULLSCREEN:
589 ee->prop.fullscreen = 1;
590 ee->engine.x.state.fullscreen = 1;
591 break;
592 case ECORE_X_WINDOW_STATE_ABOVE:
593 ee->engine.x.state.above = 1;
594 break;
595 case ECORE_X_WINDOW_STATE_BELOW:
596 ee->engine.x.state.below = 1;
597 break;
598 default:
599 break;
600 }
601 }
602 free(state);
603 }
604
605 if ((ee->prop.sticky) && (!sticky))
606 {
607 ee->prop.sticky = 0;
608 ee->engine.x.state.sticky = 0;
609 if (ee->func.fn_unsticky) ee->func.fn_unsticky(ee);
610 }
611 }
612
613 return ECORE_CALLBACK_PASS_ON;
614}
615
616static Eina_Bool
617_ecore_evas_x_event_visibility_change(void *data __UNUSED__, int type __UNUSED__, void *event)
618{
619 Ecore_Evas *ee;
620 Ecore_X_Event_Window_Visibility_Change *e;
621
622 e = event;
623 ee = ecore_event_window_match(e->win);
624 if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */
625 if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
626// printf("VIS CHANGE OBSCURED: %p %i\n", ee, e->fully_obscured);
627 if (e->fully_obscured)
628 {
629 /* FIXME: round trip */
630 if (!ecore_x_screen_is_composited(ee->engine.x.screen_num))
631 ee->draw_ok = 0;
632 }
633 else
634 ee->draw_ok = 1;
635 return ECORE_CALLBACK_PASS_ON;
636}
637
638static Eina_Bool
639_ecore_evas_x_event_client_message(void *data __UNUSED__, int type __UNUSED__, void *event)
640{
641 Ecore_Evas *ee;
642 Ecore_X_Event_Client_Message *e;
643
644 e = event;
645 if (e->format != 32) return ECORE_CALLBACK_PASS_ON;
646 if (e->message_type == ECORE_X_ATOM_E_COMP_SYNC_BEGIN)
647 {
648 ee = ecore_event_window_match(e->data.l[0]);
649 if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */
650 if (e->data.l[0] != (long)ee->prop.window)
651 return ECORE_CALLBACK_PASS_ON;
652 if (!ee->engine.x.sync_began)
653 {
654 // qeue a damage + draw. work around an event re-ordering thing.
655 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
656 }
657 ee->engine.x.sync_began = 1;
658 ee->engine.x.sync_cancel = 0;
659 }
660 else if (e->message_type == ECORE_X_ATOM_E_COMP_SYNC_END)
661 {
662 ee = ecore_event_window_match(e->data.l[0]);
663 if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */
664 if (e->data.l[0] != (long)ee->prop.window)
665 return ECORE_CALLBACK_PASS_ON;
666 ee->engine.x.sync_began = 0;
667 ee->engine.x.sync_cancel = 0;
668 }
669 else if (e->message_type == ECORE_X_ATOM_E_COMP_SYNC_CANCEL)
670 {
671 ee = ecore_event_window_match(e->data.l[0]);
672 if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */
673 if (e->data.l[0] != (long)ee->prop.window)
674 return ECORE_CALLBACK_PASS_ON;
675 ee->engine.x.sync_began = 0;
676 ee->engine.x.sync_cancel = 1;
677 }
678 else if ((e->message_type == ECORE_X_ATOM_WM_PROTOCOLS) &&
679 (e->data.l[0] == (int)ECORE_X_ATOM_NET_WM_SYNC_REQUEST))
680 {
681 ee = ecore_event_window_match(e->win);
682 if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */
683 ee->engine.x.netwm_sync_val_lo = (unsigned int)e->data.l[2];
684 ee->engine.x.netwm_sync_val_hi = (int)e->data.l[3];
685 ee->engine.x.netwm_sync_set = 1;
686 }
687 return ECORE_CALLBACK_PASS_ON;
688}
689
690static Eina_Bool
691_ecore_evas_x_event_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
692{
693 Ecore_Evas *ee;
694 Ecore_X_Event_Mouse_In *e;
695
696 e = event;
697 ee = ecore_event_window_match(e->win);
698 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; /* pass on event */
699 if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
700/* { */
701/* time_t t; */
702/* char *ct; */
703
704/* const char *modes[] = { */
705/* "MODE_NORMAL", */
706/* "MODE_WHILE_GRABBED", */
707/* "MODE_GRAB", */
708/* "MODE_UNGRAB" */
709/* }; */
710/* const char *details[] = { */
711/* "DETAIL_ANCESTOR", */
712/* "DETAIL_VIRTUAL", */
713/* "DETAIL_INFERIOR", */
714/* "DETAIL_NON_LINEAR", */
715/* "DETAIL_NON_LINEAR_VIRTUAL", */
716/* "DETAIL_POINTER", */
717/* "DETAIL_POINTER_ROOT", */
718/* "DETAIL_DETAIL_NONE" */
719/* }; */
720/* t = time(NULL); */
721/* ct = ctime(&t); */
722/* ct[strlen(ct) - 1] = 0; */
723/* printf("@@ ->IN 0x%x 0x%x %s md=%s dt=%s\n", */
724/* e->win, e->event_win, */
725/* ct, */
726/* modes[e->mode], */
727/* details[e->detail]); */
728/* } */
729 // disable. causes more problems than it fixes
730 // if ((e->mode == ECORE_X_EVENT_MODE_GRAB) ||
731 // (e->mode == ECORE_X_EVENT_MODE_UNGRAB))
732 // return 0;
733 /* if (e->mode != ECORE_X_EVENT_MODE_NORMAL) return 0; */
734 if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee);
735 ecore_event_evas_modifier_lock_update(ee->evas, e->modifiers);
736 evas_event_feed_mouse_in(ee->evas, e->time, NULL);
737 _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
738 return ECORE_CALLBACK_PASS_ON;
739}
740
741static Eina_Bool
742_ecore_evas_x_event_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
743{
744 Ecore_Evas *ee;
745 Ecore_X_Event_Mouse_Out *e;
746
747 e = event;
748 ee = ecore_event_window_match(e->win);
749 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
750 /* pass on event */
751 if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
752/* { */
753/* time_t t; */
754/* char *ct; */
755
756/* const char *modes[] = { */
757/* "MODE_NORMAL", */
758/* "MODE_WHILE_GRABBED", */
759/* "MODE_GRAB", */
760/* "MODE_UNGRAB" */
761/* }; */
762/* const char *details[] = { */
763/* "DETAIL_ANCESTOR", */
764/* "DETAIL_VIRTUAL", */
765/* "DETAIL_INFERIOR", */
766/* "DETAIL_NON_LINEAR", */
767/* "DETAIL_NON_LINEAR_VIRTUAL", */
768/* "DETAIL_POINTER", */
769/* "DETAIL_POINTER_ROOT", */
770/* "DETAIL_DETAIL_NONE" */
771/* }; */
772/* t = time(NULL); */
773/* ct = ctime(&t); */
774/* ct[strlen(ct) - 1] = 0; */
775/* printf("@@ ->OUT 0x%x 0x%x %s md=%s dt=%s\n", */
776/* e->win, e->event_win, */
777/* ct, */
778/* modes[e->mode], */
779/* details[e->detail]); */
780/* } */
781 // disable. causes more problems than it fixes
782 // if ((e->mode == ECORE_X_EVENT_MODE_GRAB) ||
783 // (e->mode == ECORE_X_EVENT_MODE_UNGRAB))
784 // return 0;
785 /* if (e->mode != ECORE_X_EVENT_MODE_NORMAL) return 0; */
786 ecore_event_evas_modifier_lock_update(ee->evas, e->modifiers);
787 _ecore_evas_mouse_move_process(ee, e->x, e->y, e->time);
788 if (e->mode == ECORE_X_EVENT_MODE_GRAB)
789 evas_event_feed_mouse_cancel(ee->evas, e->time, NULL);
790 evas_event_feed_mouse_out(ee->evas, e->time, NULL);
791 if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee);
792 if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object);
793 return ECORE_CALLBACK_PASS_ON;
794}
795
796static Eina_Bool
797_ecore_evas_x_event_window_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event)
798{
799 Ecore_Evas *ee;
800 Ecore_X_Event_Window_Focus_In *e;
801
802 e = event;
803 ee = ecore_event_window_match(e->win);
804 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; /* pass on event */
805 if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
806 if (e->mode == ECORE_X_EVENT_MODE_UNGRAB) return ECORE_CALLBACK_PASS_ON;
807 ee->prop.focused = 1;
808 evas_focus_in(ee->evas);
809 if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
810 return ECORE_CALLBACK_PASS_ON;
811}
812
813static Eina_Bool
814_ecore_evas_x_event_window_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event)
815{
816 Ecore_Evas *ee;
817 Ecore_X_Event_Window_Focus_Out *e;
818
819 e = event;
820 ee = ecore_event_window_match(e->win);
821 if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; /* pass on event */
822 if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
823 if (e->mode == ECORE_X_EVENT_MODE_GRAB) return ECORE_CALLBACK_PASS_ON;
824// if (ee->prop.fullscreen)
825// ecore_x_window_focus(ee->prop.window);
826 evas_focus_out(ee->evas);
827 ee->prop.focused = 0;
828 if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
829 return ECORE_CALLBACK_PASS_ON;
830}
831
832static Eina_Bool
833_ecore_evas_x_event_window_damage(void *data __UNUSED__, int type __UNUSED__, void *event)
834{
835 Ecore_Evas *ee;
836 Ecore_X_Event_Window_Damage *e;
837
838 e = event;
839 ee = ecore_event_window_match(e->win);
840 if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */
841 if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
842 if (ee->engine.x.using_bg_pixmap) return ECORE_CALLBACK_PASS_ON;
843// printf("EXPOSE %p [%i] %i %i %ix%i\n", ee, ee->prop.avoid_damage, e->x, e->y, e->w, e->h);
844 if (ee->prop.avoid_damage)
845 {
846 Ecore_X_Rectangle rect;
847 Ecore_X_XRegion *tmpr;
848
849 if (!ee->engine.x.damages)
850 ee->engine.x.damages = ecore_x_xregion_new();
851 tmpr = ecore_x_xregion_new();
852 rect.x = e->x;
853 rect.y = e->y;
854 rect.width = e->w;
855 rect.height = e->h;
856 ecore_x_xregion_union_rect(tmpr, ee->engine.x.damages, &rect);
857 ecore_x_xregion_free(ee->engine.x.damages);
858 ee->engine.x.damages = tmpr;
859/* no - this breaks things badly. disable. Ecore_X_Rectangle != XRectangle - see
860 * the typedefs in x's headers and ecore_x's. also same with Region - it's a pointer in x - not an X ID
861 Ecore_X_Rectangle rect;
862 Ecore_X_XRegion *tmpr;
863
864 if (!ee->engine.x.damages) ee->engine.x.damages = ecore_x_xregion_new();
865 tmpr = ecore_x_xregion_new();
866 rect.x = e->x;
867 rect.y = e->y;
868 rect.width = e->w;
869 rect.height = e->h;
870 ecore_x_xregion_union_rect(tmpr, ee->engine.x.damages, &rect);
871 ecore_x_xregion_free(ee->engine.x.damages);
872 ee->engine.x.damages = tmpr;
873 */
874 }
875 else
876 {
877 if (ee->rotation == 0)
878 evas_damage_rectangle_add(ee->evas, e->x, e->y, e->w, e->h);
879 else if (ee->rotation == 90)
880 evas_damage_rectangle_add(ee->evas,
881 ee->h - e->y - e->h, e->x, e->h, e->w);
882 else if (ee->rotation == 180)
883 evas_damage_rectangle_add(ee->evas, ee->w - e->x - e->w,
884 ee->h - e->y - e->h, e->w, e->h);
885 else if (ee->rotation == 270)
886 evas_damage_rectangle_add(ee->evas, e->y, ee->w - e->x - e->w,
887 e->h, e->w);
888 }
889 return ECORE_CALLBACK_PASS_ON;
890}
891
892static Eina_Bool
893_ecore_evas_x_event_window_destroy(void *data __UNUSED__, int type __UNUSED__, void *event)
894{
895 Ecore_Evas *ee;
896 Ecore_X_Event_Window_Destroy *e;
897
898 e = event;
899 ee = ecore_event_window_match(e->win);
900 if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */
901 if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
902 if (ee->func.fn_destroy) ee->func.fn_destroy(ee);
903 _ecore_evas_x_sync_clear(ee);
904 ecore_evas_free(ee);
905 return ECORE_CALLBACK_PASS_ON;
906}
907
908static Eina_Bool
909_ecore_evas_x_event_window_configure(void *data __UNUSED__, int type __UNUSED__, void *event)
910{
911 Ecore_Evas *ee;
912 Ecore_X_Event_Window_Configure *e;
913
914 e = event;
915 ee = ecore_event_window_match(e->win);
916 if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */
917 if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
918 if (ee->engine.x.direct_resize) return ECORE_CALLBACK_PASS_ON;
919
920 ee->engine.x.configure_coming = 0;
921 if ((e->from_wm) || (ee->prop.override))
922 {
923 if ((ee->x != e->x) || (ee->y != e->y))
924 {
925 ee->x = e->x;
926 ee->y = e->y;
927 ee->req.x = ee->x;
928 ee->req.y = ee->y;
929 if (ee->func.fn_move) ee->func.fn_move(ee);
930 }
931 }
932 if ((ee->w != e->w) || (ee->h != e->h))
933 {
934 ee->w = e->w;
935 ee->h = e->h;
936 ee->req.w = ee->w;
937 ee->req.h = ee->h;
938 if ((ee->rotation == 90) || (ee->rotation == 270))
939 {
940 evas_output_size_set(ee->evas, ee->h, ee->w);
941 evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
942 }
943 else
944 {
945 evas_output_size_set(ee->evas, ee->w, ee->h);
946 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
947 }
948 if (ee->prop.avoid_damage)
949 {
950 int pdam;
951
952 pdam = ecore_evas_avoid_damage_get(ee);
953 ecore_evas_avoid_damage_set(ee, 0);
954 ecore_evas_avoid_damage_set(ee, pdam);
955 }
956 if ((ee->shaped) || (ee->alpha))
957 _ecore_evas_x_resize_shape(ee);
958 if ((ee->expecting_resize.w > 0) && (ee->expecting_resize.h > 0))
959 {
960 if ((ee->expecting_resize.w == ee->w) &&
961 (ee->expecting_resize.h == ee->h))
962 _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y,
963 ecore_x_current_time_get());
964 ee->expecting_resize.w = 0;
965 ee->expecting_resize.h = 0;
966 }
967 if (ee->func.fn_resize) ee->func.fn_resize(ee);
968 }
969 return ECORE_CALLBACK_PASS_ON;
970}
971
972static Eina_Bool
973_ecore_evas_x_event_window_delete_request(void *data __UNUSED__, int type __UNUSED__, void *event)
974{
975 Ecore_Evas *ee;
976 Ecore_X_Event_Window_Delete_Request *e;
977
978 e = event;
979 ee = ecore_event_window_match(e->win);
980 if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */
981 if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
982 if (ee->func.fn_delete_request) ee->func.fn_delete_request(ee);
983 return ECORE_CALLBACK_PASS_ON;
984}
985
986static Eina_Bool
987_ecore_evas_x_event_window_show(void *data __UNUSED__, int type __UNUSED__, void *event)
988{
989 Ecore_Evas *ee;
990 Ecore_X_Event_Window_Show *e;
991 static int first_map_bug = -1;
992
993 e = event;
994 ee = ecore_event_window_match(e->win);
995 if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */
996 if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
997 if (first_map_bug < 0)
998 {
999 char *bug = NULL;
1000
1001 if ((bug = getenv("ECORE_EVAS_GL_FIRST_MAP_BUG")))
1002 first_map_bug = atoi(bug);
1003 else
1004 first_map_bug = 0;
1005 }
1006 if ((first_map_bug) && (!strcmp(ee->driver, "opengl_x11")))
1007 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1008 if (ee->visible) return ECORE_CALLBACK_PASS_ON;
1009// if (ee->visible) return ECORE_CALLBACK_DONE;
1010// printf("SHOW EVENT %p\n", ee);
1011 ee->visible = 1;
1012 if (ee->func.fn_show) ee->func.fn_show(ee);
1013 return ECORE_CALLBACK_PASS_ON;
1014}
1015
1016static Eina_Bool
1017_ecore_evas_x_event_window_hide(void *data __UNUSED__, int type __UNUSED__, void *event)
1018{
1019 Ecore_Evas *ee;
1020 Ecore_X_Event_Window_Hide *e;
1021
1022 e = event;
1023 ee = ecore_event_window_match(e->win);
1024 if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */
1025 if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1026 if (!ee->visible) return ECORE_CALLBACK_PASS_ON;
1027// if (!ee->visible) return ECORE_CALLBACK_DONE;
1028// printf("HIDE EVENT %p\n", ee);
1029 ee->visible = 0;
1030 if (ee->func.fn_hide) ee->func.fn_hide(ee);
1031 return ECORE_CALLBACK_PASS_ON;
1032}
1033
1034/* FIXME, should be in idler */
1035/* FIXME, round trip */
1036static void
1037_ecore_evas_x_size_pos_hints_update(Ecore_Evas *ee)
1038{
1039 ecore_x_icccm_size_pos_hints_set(ee->prop.window,
1040 ee->prop.request_pos /*request_pos */,
1041 ECORE_X_GRAVITY_NW /* gravity */,
1042 ee->prop.min.w /* min_w */,
1043 ee->prop.min.h /* min_h */,
1044 ee->prop.max.w /* max_w */,
1045 ee->prop.max.h /* max_h */,
1046 ee->prop.base.w /* base_w */,
1047 ee->prop.base.h /* base_h */,
1048 ee->prop.step.w /* step_x */,
1049 ee->prop.step.h /* step_y */,
1050 0 /* min_aspect */,
1051 0 /* max_aspect */);
1052}
1053
1054/* FIXME, should be in idler */
1055static void
1056_ecore_evas_x_state_update(Ecore_Evas *ee)
1057{
1058 Ecore_X_Window_State state[10];
1059 int num = 0;
1060
1061 /*
1062 if (bd->client.netwm.state.modal)
1063 state[num++] = ECORE_X_WINDOW_STATE_MODAL;
1064 */
1065 if (ee->engine.x.state.sticky)
1066 state[num++] = ECORE_X_WINDOW_STATE_STICKY;
1067 /*
1068 if (bd->client.netwm.state.maximized_v)
1069 state[num++] = ECORE_X_WINDOW_STATE_MAXIMIZED_VERT;
1070 if (bd->client.netwm.state.maximized_h)
1071 state[num++] = ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ;
1072 if (bd->client.netwm.state.shaded)
1073 state[num++] = ECORE_X_WINDOW_STATE_SHADED;
1074 if (bd->client.netwm.state.skip_taskbar)
1075 state[num++] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
1076 if (bd->client.netwm.state.skip_pager)
1077 state[num++] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
1078 if (bd->client.netwm.state.hidden)
1079 state[num++] = ECORE_X_WINDOW_STATE_HIDDEN;
1080 */
1081 if (ee->engine.x.state.fullscreen)
1082 state[num++] = ECORE_X_WINDOW_STATE_FULLSCREEN;
1083 if (ee->engine.x.state.above)
1084 state[num++] = ECORE_X_WINDOW_STATE_ABOVE;
1085 if (ee->engine.x.state.below)
1086 state[num++] = ECORE_X_WINDOW_STATE_BELOW;
1087
1088 ecore_x_netwm_window_state_set(ee->prop.window, state, num);
1089}
1090
1091static void
1092_ecore_evas_x_layer_update(Ecore_Evas *ee)
1093{
1094 if (ee->should_be_visible)
1095 {
1096 /* We need to send a netwm request to the wm */
1097 /* FIXME: Do we have to remove old state before adding new? */
1098 if (ee->prop.layer < 3)
1099 {
1100 if (ee->engine.x.state.above)
1101 {
1102 ee->engine.x.state.above = 0;
1103 ecore_x_netwm_state_request_send(ee->prop.window,
1104 ee->engine.x.win_root,
1105 ECORE_X_WINDOW_STATE_ABOVE, -1, 0);
1106 }
1107 if (!ee->engine.x.state.below)
1108 {
1109 ee->engine.x.state.below = 1;
1110 ecore_x_netwm_state_request_send(ee->prop.window,
1111 ee->engine.x.win_root,
1112 ECORE_X_WINDOW_STATE_BELOW, -1, 1);
1113 }
1114 }
1115 else if (ee->prop.layer > 5)
1116 {
1117 if (ee->engine.x.state.below)
1118 {
1119 ee->engine.x.state.below = 0;
1120 ecore_x_netwm_state_request_send(ee->prop.window,
1121 ee->engine.x.win_root,
1122 ECORE_X_WINDOW_STATE_BELOW, -1, 0);
1123 }
1124 if (!ee->engine.x.state.above)
1125 {
1126 ee->engine.x.state.above = 1;
1127 ecore_x_netwm_state_request_send(ee->prop.window,
1128 ee->engine.x.win_root,
1129 ECORE_X_WINDOW_STATE_ABOVE, -1, 1);
1130 }
1131 }
1132 else
1133 {
1134 if (ee->engine.x.state.below)
1135 {
1136 ee->engine.x.state.below = 0;
1137 ecore_x_netwm_state_request_send(ee->prop.window,
1138 ee->engine.x.win_root,
1139 ECORE_X_WINDOW_STATE_BELOW, -1, 0);
1140 }
1141 if (ee->engine.x.state.above)
1142 {
1143 ee->engine.x.state.above = 0;
1144 ecore_x_netwm_state_request_send(ee->prop.window,
1145 ee->engine.x.win_root,
1146 ECORE_X_WINDOW_STATE_ABOVE, -1, 0);
1147 }
1148 }
1149 }
1150 else
1151 {
1152 /* Just set the state */
1153 if (ee->prop.layer < 3)
1154 {
1155 if ((ee->engine.x.state.above) || (!ee->engine.x.state.below))
1156 {
1157 ee->engine.x.state.above = 0;
1158 ee->engine.x.state.below = 1;
1159 _ecore_evas_x_state_update(ee);
1160 }
1161 }
1162 else if (ee->prop.layer > 5)
1163 {
1164 if ((!ee->engine.x.state.above) || (ee->engine.x.state.below))
1165 {
1166 ee->engine.x.state.above = 1;
1167 ee->engine.x.state.below = 0;
1168 _ecore_evas_x_state_update(ee);
1169 }
1170 }
1171 else
1172 {
1173 if ((ee->engine.x.state.above) || (ee->engine.x.state.below))
1174 {
1175 ee->engine.x.state.above = 0;
1176 ee->engine.x.state.below = 0;
1177 _ecore_evas_x_state_update(ee);
1178 }
1179 }
1180 }
1181 /* FIXME: Set gnome layer */
1182}
1183
1184static int
1185_ecore_evas_x_init(void)
1186{
1187 _ecore_evas_init_count++;
1188 if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
1189 ecore_evas_event_handlers[0] =
1190 ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN,
1191 _ecore_evas_x_event_mouse_in, NULL);
1192 ecore_evas_event_handlers[1] =
1193 ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT,
1194 _ecore_evas_x_event_mouse_out, NULL);
1195 ecore_evas_event_handlers[2] =
1196 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN,
1197 _ecore_evas_x_event_window_focus_in, NULL);
1198 ecore_evas_event_handlers[3] =
1199 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT,
1200 _ecore_evas_x_event_window_focus_out, NULL);
1201 ecore_evas_event_handlers[4] =
1202 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DAMAGE,
1203 _ecore_evas_x_event_window_damage, NULL);
1204 ecore_evas_event_handlers[5] =
1205 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY,
1206 _ecore_evas_x_event_window_destroy, NULL);
1207 ecore_evas_event_handlers[6] =
1208 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE,
1209 _ecore_evas_x_event_window_configure, NULL);
1210 ecore_evas_event_handlers[7] =
1211 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST,
1212 _ecore_evas_x_event_window_delete_request, NULL);
1213 ecore_evas_event_handlers[8] =
1214 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW,
1215 _ecore_evas_x_event_window_show, NULL);
1216 ecore_evas_event_handlers[9] =
1217 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE,
1218 _ecore_evas_x_event_window_hide, NULL);
1219 ecore_evas_event_handlers[10] =
1220 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY,
1221 _ecore_evas_x_event_property_change, NULL);
1222 ecore_evas_event_handlers[11] =
1223 ecore_event_handler_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE,
1224 _ecore_evas_x_event_visibility_change, NULL);
1225 ecore_evas_event_handlers[12] =
1226 ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE,
1227 _ecore_evas_x_event_client_message, NULL);
1228 ecore_event_evas_init();
1229 return _ecore_evas_init_count;
1230}
1231
1232static void
1233_ecore_evas_x_free(Ecore_Evas *ee)
1234{
1235 _ecore_evas_x_group_leader_unset(ee);
1236 _ecore_evas_x_sync_set(ee);
1237 if (ee->engine.x.win_shaped_input)
1238 ecore_x_window_free(ee->engine.x.win_shaped_input);
1239 ecore_x_window_free(ee->prop.window);
1240 if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap);
1241 if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1242 if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc);
1243 if (ee->engine.x.damages) ecore_x_xregion_free(ee->engine.x.damages);
1244 ee->engine.x.pmap = 0;
1245 ee->engine.x.mask = 0;
1246 ee->engine.x.gc = 0;
1247 ee->engine.x.damages = NULL;
1248 ecore_event_window_unregister(ee->prop.window);
1249 while (ee->engine.x.win_extra)
1250 {
1251 Ecore_X_Window *winp;
1252
1253 winp = ee->engine.x.win_extra->data;
1254 ee->engine.x.win_extra =
1255 eina_list_remove_list(ee->engine.x.win_extra, ee->engine.x.win_extra);
1256 ecore_event_window_unregister(*winp);
1257 free(winp);
1258 }
1259 _ecore_evas_x_shutdown();
1260 ecore_x_shutdown();
1261}
1262
1263static void
1264_ecore_evas_x_callback_delete_request_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
1265{
1266 ee->func.fn_delete_request = func;
1267 _ecore_evas_x_protocols_set(ee);
1268 _ecore_evas_x_sync_set(ee);
1269}
1270
1271static void
1272_ecore_evas_x_move(Ecore_Evas *ee, int x, int y)
1273{
1274 ee->req.x = x;
1275 ee->req.y = y;
1276 if (ee->engine.x.direct_resize)
1277 {
1278 if (!ee->engine.x.managed)
1279 {
1280 if ((x != ee->x) || (y != ee->y))
1281 {
1282 ee->x = x;
1283 ee->y = y;
1284 ecore_x_window_move(ee->prop.window, x, y);
1285 if (!ee->should_be_visible)
1286 {
1287 /* We need to request pos */
1288 ee->prop.request_pos = 1;
1289 _ecore_evas_x_size_pos_hints_update(ee);
1290 }
1291 if (ee->func.fn_move) ee->func.fn_move(ee);
1292 }
1293 }
1294 }
1295 else
1296 {
1297 if (((ee->x != x) || (ee->y != y)) ||
1298 (ee->engine.x.configure_coming))
1299 {
1300 ee->engine.x.configure_coming = 1;
1301 if (!ee->engine.x.managed)
1302 {
1303 ee->x = x;
1304 ee->y = y;
1305 }
1306 ecore_x_window_move(ee->prop.window, x, y);
1307 }
1308 if (!ee->should_be_visible)
1309 {
1310 /* We need to request pos */
1311 ee->prop.request_pos = 1;
1312 _ecore_evas_x_size_pos_hints_update(ee);
1313 }
1314 }
1315}
1316
1317static void
1318_ecore_evas_x_managed_move(Ecore_Evas *ee, int x, int y)
1319{
1320 ee->req.x = x;
1321 ee->req.y = y;
1322 if (ee->engine.x.direct_resize)
1323 {
1324 ee->engine.x.managed = 1;
1325 if ((x != ee->x) || (y != ee->y))
1326 {
1327 ee->x = x;
1328 ee->y = y;
1329 if (ee->func.fn_move) ee->func.fn_move(ee);
1330 }
1331 }
1332}
1333
1334static void
1335_ecore_evas_x_resize(Ecore_Evas *ee, int w, int h)
1336{
1337 ee->req.w = w;
1338 ee->req.h = h;
1339 if (ee->engine.x.direct_resize)
1340 {
1341 if ((ee->w != w) || (ee->h != h))
1342 {
1343 ee->w = w;
1344 ee->h = h;
1345 ecore_x_window_resize(ee->prop.window, w, h);
1346 if ((ee->rotation == 90) || (ee->rotation == 270))
1347 {
1348 evas_output_size_set(ee->evas, ee->h, ee->w);
1349 evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
1350 }
1351 else
1352 {
1353 evas_output_size_set(ee->evas, ee->w, ee->h);
1354 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
1355 }
1356 if (ee->prop.avoid_damage)
1357 {
1358 int pdam;
1359
1360 pdam = ecore_evas_avoid_damage_get(ee);
1361 ecore_evas_avoid_damage_set(ee, 0);
1362 ecore_evas_avoid_damage_set(ee, pdam);
1363 }
1364 if ((ee->shaped) || (ee->alpha))
1365 _ecore_evas_x_resize_shape(ee);
1366 if (ee->func.fn_resize) ee->func.fn_resize(ee);
1367 }
1368 }
1369 else if (((ee->w != w) || (ee->h != h)) ||
1370 (ee->engine.x.configure_coming))
1371 {
1372 ee->engine.x.configure_coming = 1;
1373 ecore_x_window_resize(ee->prop.window, w, h);
1374 }
1375}
1376
1377static void
1378_ecore_evas_x_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
1379{
1380 ee->req.x = x;
1381 ee->req.y = y;
1382 ee->req.w = w;
1383 ee->req.h = h;
1384 if (ee->engine.x.direct_resize)
1385 {
1386 if ((ee->w != w) || (ee->h != h) || (x != ee->x) || (y != ee->y))
1387 {
1388 int change_size = 0, change_pos = 0;
1389
1390 if ((ee->w != w) || (ee->h != h)) change_size = 1;
1391 if (!ee->engine.x.managed)
1392 {
1393 if ((x != ee->x) || (y != ee->y)) change_pos = 1;
1394 }
1395 ecore_x_window_move_resize(ee->prop.window, x, y, w, h);
1396 if (!ee->engine.x.managed)
1397 {
1398 ee->x = x;
1399 ee->y = y;
1400 }
1401 ee->w = w;
1402 ee->h = h;
1403 if ((ee->rotation == 90) || (ee->rotation == 270))
1404 {
1405 evas_output_size_set(ee->evas, ee->h, ee->w);
1406 evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
1407 }
1408 else
1409 {
1410 evas_output_size_set(ee->evas, ee->w, ee->h);
1411 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
1412 }
1413 if (ee->prop.avoid_damage)
1414 {
1415 int pdam;
1416
1417 pdam = ecore_evas_avoid_damage_get(ee);
1418 ecore_evas_avoid_damage_set(ee, 0);
1419 ecore_evas_avoid_damage_set(ee, pdam);
1420 }
1421 if ((ee->shaped) || (ee->alpha))
1422 _ecore_evas_x_resize_shape(ee);
1423 if (change_pos)
1424 {
1425 if (ee->func.fn_move) ee->func.fn_move(ee);
1426 }
1427 if (change_size)
1428 {
1429 if (ee->func.fn_resize) ee->func.fn_resize(ee);
1430 }
1431 }
1432 }
1433 else if (((ee->w != w) || (ee->h != h) || (ee->x != x) || (ee->y != y)) ||
1434 (ee->engine.x.configure_coming))
1435 {
1436 ee->engine.x.configure_coming = 1;
1437 ecore_x_window_move_resize(ee->prop.window, x, y, w, h);
1438 if (!ee->engine.x.managed)
1439 {
1440 ee->x = x;
1441 ee->y = y;
1442 }
1443 }
1444}
1445
1446static void
1447_ecore_evas_x_rotation_set_internal(Ecore_Evas *ee, int rotation, int resize,
1448 Evas_Engine_Info *einfo)
1449{
1450 int rot_dif;
1451
1452 rot_dif = ee->rotation - rotation;
1453 if (rot_dif < 0) rot_dif = -rot_dif;
1454
1455 if (rot_dif != 180)
1456 {
1457 int minw, minh, maxw, maxh, basew, baseh, stepw, steph;
1458
1459 if (!evas_engine_info_set(ee->evas, einfo))
1460 {
1461 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1462 }
1463
1464 if (!resize)
1465 {
1466 ee->engine.x.configure_coming = 1;
1467 if (!ee->prop.fullscreen)
1468 {
1469 ecore_x_window_resize(ee->prop.window, ee->req.h, ee->req.w);
1470 ee->expecting_resize.w = ee->h;
1471 ee->expecting_resize.h = ee->w;
1472 }
1473 else
1474 {
1475 int w, h;
1476
1477 ecore_x_window_size_get(ee->prop.window, &w, &h);
1478 ecore_x_window_resize(ee->prop.window, h, w);
1479 if ((rotation == 0) || (rotation == 180))
1480 {
1481 evas_output_size_set(ee->evas, ee->req.w, ee->req.h);
1482 evas_output_viewport_set(ee->evas, 0, 0, ee->req.w, ee->req.h);
1483 }
1484 else
1485 {
1486 evas_output_size_set(ee->evas, ee->req.h, ee->req.w);
1487 evas_output_viewport_set(ee->evas, 0, 0, ee->req.h, ee->req.w);
1488 }
1489 if (ee->func.fn_resize) ee->func.fn_resize(ee);
1490 }
1491 if ((ee->rotation == 90) || (ee->rotation == 270))
1492 evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.h, ee->req.w);
1493 else
1494 evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
1495 }
1496 else
1497 {
1498 /* int w, h; */
1499
1500 /* ecore_x_window_size_get(ee->prop.window, &w, &h); */
1501 if ((rotation == 0) || (rotation == 180))
1502 {
1503 evas_output_size_set(ee->evas, ee->w, ee->h);
1504 evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
1505 }
1506 else
1507 {
1508 evas_output_size_set(ee->evas, ee->h, ee->w);
1509 evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
1510 }
1511 if (ee->func.fn_resize) ee->func.fn_resize(ee);
1512 if ((ee->rotation == 90) || (ee->rotation == 270))
1513 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
1514 else
1515 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1516 }
1517 ecore_evas_size_min_get(ee, &minw, &minh);
1518 ecore_evas_size_max_get(ee, &maxw, &maxh);
1519 ecore_evas_size_base_get(ee, &basew, &baseh);
1520 ecore_evas_size_step_get(ee, &stepw, &steph);
1521 ee->rotation = rotation;
1522 ecore_evas_size_min_set(ee, minh, minw);
1523 ecore_evas_size_max_set(ee, maxh, maxw);
1524 ecore_evas_size_base_set(ee, baseh, basew);
1525 ecore_evas_size_step_set(ee, steph, stepw);
1526 _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y,
1527 ecore_x_current_time_get());
1528 }
1529 else
1530 {
1531 if (!evas_engine_info_set(ee->evas, einfo))
1532 {
1533 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1534 }
1535 ee->rotation = rotation;
1536 _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y,
1537 ecore_x_current_time_get());
1538 if (ee->func.fn_resize) ee->func.fn_resize(ee);
1539
1540 if ((ee->rotation == 90) || (ee->rotation == 270))
1541 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
1542 else
1543 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1544 }
1545}
1546
1547static void
1548_ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize)
1549{
1550 if (ee->rotation == rotation) return;
1551 if (!strcmp(ee->driver, "opengl_x11"))
1552 {
1553#ifdef BUILD_ECORE_EVAS_OPENGL_X11
1554 Evas_Engine_Info_GL_X11 *einfo;
1555
1556 einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
1557 if (!einfo) return;
1558 einfo->info.rotation = rotation;
1559 _ecore_evas_x_rotation_set_internal(ee, rotation, resize,
1560 (Evas_Engine_Info *)einfo);
1561#endif /* BUILD_ECORE_EVAS_OPENGL_X11 */
1562 }
1563 else if (!strcmp(ee->driver, "software_x11"))
1564 {
1565#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
1566 Evas_Engine_Info_Software_X11 *einfo;
1567
1568 einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
1569 if (!einfo) return;
1570 einfo->info.rotation = rotation;
1571 _ecore_evas_x_rotation_set_internal(ee, rotation, resize,
1572 (Evas_Engine_Info *)einfo);
1573#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
1574 }
1575 else if (!strcmp(ee->driver, "software_16_x11"))
1576 {
1577#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
1578 Evas_Engine_Info_Software_16_X11 *einfo;
1579
1580 einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
1581 if (!einfo) return;
1582 einfo->info.rotation = rotation;
1583 _ecore_evas_x_rotation_set_internal(ee, rotation, resize,
1584 (Evas_Engine_Info *)einfo);
1585#endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
1586 }
1587 else if (!strcmp(ee->driver, "software_8_x11"))
1588 {
1589#if BUILD_ECORE_EVAS_SOFTWARE_8_X11
1590 Evas_Engine_Info_Software_8_X11 *einfo;
1591
1592 einfo = (Evas_Engine_Info_Software_8_X11 *)evas_engine_info_get(ee->evas);
1593 if (!einfo) return;
1594 einfo->info.rotation = rotation;
1595 _ecore_evas_x_rotation_set_internal(ee, rotation, resize,
1596 (Evas_Engine_Info *)einfo);
1597#endif /* BUILD_ECORE_EVAS_SOFTWARE_8_X11 */
1598 }
1599}
1600
1601static void
1602_ecore_evas_x_shaped_set(Ecore_Evas *ee, int shaped)
1603{
1604 if ((ee->shaped == shaped)) return;
1605 if (!strcmp(ee->driver, "opengl_x11")) return;
1606 if (!strcmp(ee->driver, "software_x11"))
1607 {
1608#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
1609 Evas_Engine_Info_Software_X11 *einfo;
1610
1611 einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
1612 ee->shaped = shaped;
1613 if (einfo)
1614 {
1615 if (ee->shaped)
1616 {
1617 unsigned int foreground;
1618 Ecore_X_GC gc;
1619
1620 if (!ee->engine.x.mask)
1621 ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
1622 foreground = 0;
1623 gc = ecore_x_gc_new(ee->engine.x.mask,
1624 ECORE_X_GC_VALUE_MASK_FOREGROUND,
1625 &foreground);
1626 ecore_x_drawable_rectangle_fill(ee->engine.x.mask, gc,
1627 0, 0, ee->w, ee->h);
1628 ecore_x_gc_free(gc);
1629 einfo->info.mask = ee->engine.x.mask;
1630 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1631 {
1632 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1633 }
1634 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1635 ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1636 }
1637 else
1638 {
1639 if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1640 ee->engine.x.mask = 0;
1641 einfo->info.mask = 0;
1642 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1643 {
1644 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1645 }
1646 ecore_x_window_shape_mask_set(ee->prop.window, 0);
1647 ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1648 }
1649 }
1650#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
1651 }
1652 else if (!strcmp(ee->driver, "software_16_x11"))
1653 {
1654#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
1655# if 0 /* XXX no shaped window support for software_16_x11 */
1656 Evas_Engine_Info_Software_16_X11 *einfo;
1657
1658 einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
1659 ee->shaped = shaped;
1660 if (einfo)
1661 {
1662 if (ee->shaped)
1663 {
1664 ee->engine.x.mask =
1665 ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
1666 einfo->info.mask = ee->engine.x.mask;
1667 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1668 {
1669 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1670 }
1671 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1672 }
1673 else
1674 {
1675 if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1676 ee->engine.x.mask = 0;
1677 einfo->info.mask = 0;
1678 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1679 {
1680 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1681 }
1682 ecore_x_window_shape_mask_set(ee->prop.window, 0);
1683 }
1684 }
1685# endif /* XXX no shaped window support for software_16_x11 */
1686#endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
1687 }
1688 if (!strcmp(ee->driver, "software_8_x11"))
1689 {
1690#if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
1691 Evas_Engine_Info_Software_8_X11 *einfo;
1692
1693 einfo = (Evas_Engine_Info_Software_8_X11 *)evas_engine_info_get(ee->evas);
1694 ee->shaped = shaped;
1695 if (einfo)
1696 {
1697 if (ee->shaped)
1698 {
1699 unsigned int foreground;
1700 Ecore_X_GC gc;
1701
1702 if (!ee->engine.x.mask)
1703 ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
1704 foreground = 0;
1705 gc = ecore_x_gc_new(ee->engine.x.mask,
1706 ECORE_X_GC_VALUE_MASK_FOREGROUND,
1707 &foreground);
1708 ecore_x_drawable_rectangle_fill(ee->engine.x.mask, gc,
1709 0, 0, ee->w, ee->h);
1710 ecore_x_gc_free(gc);
1711 einfo->info.mask = ee->engine.x.mask;
1712 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1713 {
1714 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1715 }
1716 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1717 ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1718 }
1719 else
1720 {
1721 if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1722 ee->engine.x.mask = 0;
1723 einfo->info.mask = 0;
1724 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1725 {
1726 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1727 }
1728 ecore_x_window_shape_mask_set(ee->prop.window, 0);
1729 ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1730 }
1731 }
1732#endif /* BUILD_ECORE_EVAS_SOFTWARE_8_X11 */
1733 }
1734}
1735
1736/* FIXME, round trip */
1737static void
1738_ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha)
1739{
1740 Ecore_X_Window_Attributes att;
1741 char *id = NULL;
1742
1743 if ((ee->alpha == alpha)) return;
1744
1745 if (!strcmp(ee->driver, "software_x11"))
1746 {
1747#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
1748 Evas_Engine_Info_Software_X11 *einfo;
1749
1750 einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
1751 if (!einfo) return;
1752
1753 if (!ecore_x_composite_query()) return;
1754
1755 ee->shaped = 0;
1756 ee->alpha = alpha;
1757 ecore_x_window_free(ee->prop.window);
1758 ecore_event_window_unregister(ee->prop.window);
1759 if (ee->alpha)
1760 {
1761 if (ee->prop.override)
1762 ee->prop.window = ecore_x_window_override_argb_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
1763 else
1764 ee->prop.window = ecore_x_window_argb_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
1765 if (!ee->engine.x.mask)
1766 ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
1767 }
1768 else
1769 {
1770 if (ee->prop.override)
1771 ee->prop.window = ecore_x_window_override_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
1772 else
1773 ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
1774 if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1775 ee->engine.x.mask = 0;
1776 ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1777 }
1778
1779 einfo->info.destination_alpha = alpha;
1780
1781 ecore_x_window_attributes_get(ee->prop.window, &att);
1782 einfo->info.visual = att.visual;
1783 einfo->info.colormap = att.colormap;
1784 einfo->info.depth = att.depth;
1785
1786// if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1787// ee->engine.x.mask = 0;
1788 einfo->info.mask = ee->engine.x.mask;
1789 einfo->info.drawable = ee->prop.window;
1790 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1791 {
1792 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1793 }
1794 evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
1795 ecore_x_window_shape_mask_set(ee->prop.window, 0);
1796 ecore_x_input_multi_select(ee->prop.window);
1797 ecore_event_window_register(ee->prop.window, ee, ee->evas,
1798 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
1799 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
1800 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
1801 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
1802 if (ee->prop.borderless)
1803 ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
1804 if (ee->visible) ecore_x_window_show(ee->prop.window);
1805 if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
1806 if (ee->prop.title)
1807 {
1808 ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
1809 ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
1810 }
1811 ecore_x_icccm_hints_set(ee->prop.window,
1812 1 /* accepts_focus */,
1813 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
1814 0 /* icon_pixmap */,
1815 0 /* icon_mask */,
1816 0 /* icon_window */,
1817 0 /* window_group */,
1818 0 /* is_urgent */);
1819 _ecore_evas_x_group_leader_update(ee);
1820 ecore_x_window_defaults_set(ee->prop.window);
1821 _ecore_evas_x_protocols_set(ee);
1822 _ecore_evas_x_sync_set(ee);
1823#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
1824 if ((id = getenv("DESKTOP_STARTUP_ID")))
1825 {
1826 ecore_x_netwm_startup_id_set(ee->prop.window, id);
1827 /* NB: on linux this may simply empty the env as opposed to completely
1828 * unset it to being empty - unsure as solartis libc crashes looking
1829 * for the '=' char */
1830 // putenv((char*)"DESKTOP_STARTUP_ID=");
1831 }
1832 }
1833 else if (!strcmp(ee->driver, "opengl_x11"))
1834 {
1835#ifdef BUILD_ECORE_EVAS_OPENGL_X11
1836 Evas_Engine_Info_GL_X11 *einfo;
1837
1838 einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
1839 if (!einfo) return;
1840
1841 if (!ecore_x_composite_query()) return;
1842
1843 ee->shaped = 0;
1844 ee->alpha = alpha;
1845 ecore_x_window_free(ee->prop.window);
1846 ecore_event_window_unregister(ee->prop.window);
1847 ee->prop.window = 0;
1848
1849 einfo->info.destination_alpha = alpha;
1850
1851 if (ee->engine.x.win_root != 0)
1852 {
1853 /* FIXME: round trip in ecore_x_window_argb_get */
1854 if (ecore_x_window_argb_get(ee->engine.x.win_root))
1855 {
1856 ee->prop.window =
1857 _ecore_evas_x_gl_window_new(ee, ee->engine.x.win_root,
1858 ee->req.x, ee->req.y,
1859 ee->req.w, ee->req.h,
1860 ee->prop.override, 1, NULL);
1861 }
1862 else
1863 {
1864 ee->prop.window =
1865 _ecore_evas_x_gl_window_new(ee, ee->engine.x.win_root,
1866 ee->req.x, ee->req.y,
1867 ee->req.w, ee->req.h,
1868 ee->prop.override, ee->alpha,
1869 NULL);
1870 }
1871 }
1872 else
1873 {
1874 ee->prop.window =
1875 _ecore_evas_x_gl_window_new(ee, ee->engine.x.win_root,
1876 ee->req.x, ee->req.y,
1877 ee->req.w, ee->req.h,
1878 ee->prop.override, ee->alpha, NULL);
1879 }
1880
1881 if (!ee->prop.window) return;
1882/*
1883 if (ee->alpha)
1884 {
1885 if (ee->prop.override)
1886 ee->prop.window = ecore_x_window_override_argb_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
1887 else
1888 ee->prop.window = ecore_x_window_argb_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
1889 if (!ee->engine.x.mask)
1890 ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
1891 }
1892 else
1893 {
1894 if (ee->prop.override)
1895 ee->prop.window = ecore_x_window_override_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
1896 else
1897 ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
1898 if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1899 ee->engine.x.mask = 0;
1900 ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1901 }
1902 */
1903
1904 ecore_x_window_attributes_get(ee->prop.window, &att);
1905 einfo->info.visual = att.visual;
1906 einfo->info.colormap = att.colormap;
1907 einfo->info.depth = att.depth;
1908
1909// if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1910// ee->engine.x.mask = 0;
1911// einfo->info.mask = ee->engine.x.mask;
1912 einfo->info.drawable = ee->prop.window;
1913 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1914 {
1915 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1916 }
1917 evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
1918// ecore_x_window_shape_mask_set(ee->prop.window, 0);
1919 ecore_x_input_multi_select(ee->prop.window);
1920 ecore_event_window_register(ee->prop.window, ee, ee->evas,
1921 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
1922 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
1923 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
1924 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
1925 if (ee->prop.borderless)
1926 ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
1927 if (ee->visible) ecore_x_window_show(ee->prop.window);
1928 if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
1929 if (ee->prop.title)
1930 {
1931 ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
1932 ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
1933 }
1934 ecore_x_icccm_hints_set(ee->prop.window,
1935 1 /* accepts_focus */,
1936 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
1937 0 /* icon_pixmap */,
1938 0 /* icon_mask */,
1939 0 /* icon_window */,
1940 0 /* window_group */,
1941 0 /* is_urgent */);
1942 _ecore_evas_x_group_leader_update(ee);
1943 ecore_x_window_defaults_set(ee->prop.window);
1944 _ecore_evas_x_protocols_set(ee);
1945 _ecore_evas_x_sync_set(ee);
1946#endif /* BUILD_ECORE_EVAS_OPENGL_X11 */
1947 if ((id = getenv("DESKTOP_STARTUP_ID")))
1948 {
1949 ecore_x_netwm_startup_id_set(ee->prop.window, id);
1950 /* NB: on linux this may simply empty the env as opposed to completely
1951 * unset it to being empty - unsure as solartis libc crashes looking
1952 * for the '=' char */
1953 // putenv((char*)"DESKTOP_STARTUP_ID=");
1954 }
1955 }
1956 else if (!strcmp(ee->driver, "software_16_x11"))
1957 {
1958#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
1959 Evas_Engine_Info_Software_16_X11 *einfo;
1960
1961 einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
1962 if (!einfo) return;
1963
1964 ee->shaped = 0;
1965 ee->alpha = alpha;
1966 ecore_x_window_free(ee->prop.window);
1967 ecore_event_window_unregister(ee->prop.window);
1968 if (ee->alpha)
1969 {
1970 if (ee->prop.override)
1971 ee->prop.window = ecore_x_window_override_argb_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
1972 else
1973 ee->prop.window = ecore_x_window_argb_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
1974 if (!ee->engine.x.mask)
1975 ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
1976 }
1977 else
1978 {
1979 if (ee->prop.override)
1980 ee->prop.window = ecore_x_window_override_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
1981 else
1982 ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
1983 if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1984 ee->engine.x.mask = 0;
1985 ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1986 }
1987
1988# if 0 /* XXX no alpha window support for software_16_x11 */
1989 einfo->info.destination_alpha = alpha;
1990# endif /* XXX no alpha window support for software_16_x11 */
1991
1992# if 0 /* XXX no shaped window support for software_16_x11 */
1993// if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1994// ee->engine.x.mask = 0;
1995 einfo->info.mask = ee->engine.x.mask;
1996# endif /* XXX no shaped window support for software_16_x11 */
1997
1998 einfo->info.drawable = ee->prop.window;
1999 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2000 {
2001 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2002 }
2003 evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
2004 ecore_x_window_shape_mask_set(ee->prop.window, 0);
2005 ecore_x_input_multi_select(ee->prop.window);
2006 ecore_event_window_register(ee->prop.window, ee, ee->evas,
2007 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
2008 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
2009 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
2010 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
2011 if (ee->prop.borderless)
2012 ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
2013 if (ee->visible) ecore_x_window_show(ee->prop.window);
2014 if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
2015 if (ee->prop.title)
2016 {
2017 ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
2018 ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
2019 }
2020 ecore_x_icccm_hints_set(ee->prop.window,
2021 1 /* accepts_focus */,
2022 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2023 0 /* icon_pixmap */,
2024 0 /* icon_mask */,
2025 0 /* icon_window */,
2026 0 /* window_group */,
2027 0 /* is_urgent */);
2028 _ecore_evas_x_group_leader_update(ee);
2029 ecore_x_window_defaults_set(ee->prop.window);
2030 _ecore_evas_x_protocols_set(ee);
2031 _ecore_evas_x_sync_set(ee);
2032#endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
2033 if ((id = getenv("DESKTOP_STARTUP_ID")))
2034 {
2035 ecore_x_netwm_startup_id_set(ee->prop.window, id);
2036 /* NB: on linux this may simply empty the env as opposed to completely
2037 * unset it to being empty - unsure as solartis libc crashes looking
2038 * for the '=' char */
2039 // putenv((char*)"DESKTOP_STARTUP_ID=");
2040 }
2041 }
2042 else if (!strcmp(ee->driver, "software_8_x11"))
2043 {
2044#if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
2045 Evas_Engine_Info_Software_8_X11 *einfo;
2046
2047 einfo = (Evas_Engine_Info_Software_8_X11 *)evas_engine_info_get(ee->evas);
2048 if (!einfo) return;
2049
2050 ee->shaped = 0;
2051 ee->alpha = alpha;
2052 ecore_x_window_free(ee->prop.window);
2053 ecore_event_window_unregister(ee->prop.window);
2054 if (ee->alpha)
2055 {
2056 if (ee->prop.override)
2057 ee->prop.window = ecore_x_window_override_argb_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
2058 else
2059 ee->prop.window = ecore_x_window_argb_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
2060 if (!ee->engine.x.mask)
2061 ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
2062 }
2063 else
2064 {
2065 if (ee->prop.override)
2066 ee->prop.window = ecore_x_window_override_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
2067 else
2068 ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
2069 if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
2070 ee->engine.x.mask = 0;
2071 ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
2072 }
2073
2074 einfo->info.destination_alpha = alpha;
2075
2076 ecore_x_window_attributes_get(ee->prop.window, &att);
2077 einfo->info.visual = att.visual;
2078 einfo->info.colormap = att.colormap;
2079 einfo->info.depth = att.depth;
2080
2081// if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
2082// ee->engine.x.mask = 0;
2083 einfo->info.mask = ee->engine.x.mask;
2084 einfo->info.drawable = ee->prop.window;
2085 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2086 {
2087 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2088 }
2089 evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
2090 ecore_x_window_shape_mask_set(ee->prop.window, 0);
2091 ecore_x_input_multi_select(ee->prop.window);
2092 ecore_event_window_register(ee->prop.window, ee, ee->evas,
2093 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
2094 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
2095 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
2096 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
2097 if (ee->prop.borderless)
2098 ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
2099 if (ee->visible) ecore_x_window_show(ee->prop.window);
2100 if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
2101 if (ee->prop.title)
2102 {
2103 ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
2104 ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
2105 }
2106 ecore_x_icccm_hints_set(ee->prop.window,
2107 1 /* accepts_focus */,
2108 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2109 0 /* icon_pixmap */,
2110 0 /* icon_mask */,
2111 0 /* icon_window */,
2112 0 /* window_group */,
2113 0 /* is_urgent */);
2114 _ecore_evas_x_group_leader_update(ee);
2115 ecore_x_window_defaults_set(ee->prop.window);
2116 _ecore_evas_x_protocols_set(ee);
2117 _ecore_evas_x_sync_set(ee);
2118
2119 if ((id = getenv("DESKTOP_STARTUP_ID")))
2120 {
2121 ecore_x_netwm_startup_id_set(ee->prop.window, id);
2122 /* NB: on linux this may simply empty the env as opposed to completely
2123 * unset it to being empty - unsure as solartis libc crashes looking
2124 * for the '=' char */
2125 // putenv((char*)"DESKTOP_STARTUP_ID=");
2126 }
2127#endif /* BUILD_ECORE_EVAS_SOFTWARE_8_X11 */
2128 }
2129}
2130
2131static void
2132_ecore_evas_x_transparent_set(Ecore_Evas *ee, int transparent)
2133{
2134 if ((ee->transparent == transparent)) return;
2135
2136 if (!strcmp(ee->driver, "software_x11"))
2137 {
2138#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
2139 Evas_Engine_Info_Software_X11 *einfo;
2140
2141 einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
2142 if (!einfo) return;
2143
2144 ee->transparent = transparent;
2145 einfo->info.destination_alpha = transparent;
2146 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2147 {
2148 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2149 }
2150 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
2151#endif
2152 }
2153}
2154#endif /* BUILD_ECORE_EVAS_X11 */
2155
2156#ifdef BUILD_ECORE_EVAS_X11
2157static void
2158_ecore_evas_x_show(Ecore_Evas *ee)
2159{
2160 ee->should_be_visible = 1;
2161 if (ee->prop.avoid_damage)
2162 _ecore_evas_x_render(ee);
2163 _ecore_evas_x_sync_set(ee);
2164 ecore_x_window_show(ee->prop.window);
2165 if (ee->prop.fullscreen)
2166 ecore_x_window_focus(ee->prop.window);
2167}
2168
2169static void
2170_ecore_evas_x_hide(Ecore_Evas *ee)
2171{
2172 ecore_x_window_hide(ee->prop.window);
2173 ee->should_be_visible = 0;
2174 _ecore_evas_x_sync_set(ee);
2175}
2176
2177static void
2178_ecore_evas_x_raise(Ecore_Evas *ee)
2179{
2180 ecore_x_window_raise(ee->prop.window);
2181}
2182
2183static void
2184_ecore_evas_x_lower(Ecore_Evas *ee)
2185{
2186 ecore_x_window_lower(ee->prop.window);
2187}
2188
2189static void
2190_ecore_evas_x_activate(Ecore_Evas *ee)
2191{
2192 ecore_x_netwm_client_active_request(ee->engine.x.win_root,
2193 ee->prop.window, 2, 0);
2194}
2195
2196static void
2197_ecore_evas_x_title_set(Ecore_Evas *ee, const char *t)
2198{
2199 if (ee->prop.title) free(ee->prop.title);
2200 ee->prop.title = NULL;
2201 if (t) ee->prop.title = strdup(t);
2202 ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
2203 ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
2204}
2205
2206static void
2207_ecore_evas_x_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
2208{
2209 if (ee->prop.name) free(ee->prop.name);
2210 if (ee->prop.clas) free(ee->prop.clas);
2211 ee->prop.name = NULL;
2212 ee->prop.clas = NULL;
2213 if (n) ee->prop.name = strdup(n);
2214 if (c) ee->prop.clas = strdup(c);
2215 ecore_x_icccm_name_class_set(ee->prop.window, ee->prop.name, ee->prop.clas);
2216}
2217
2218static void
2219_ecore_evas_x_size_min_set(Ecore_Evas *ee, int w, int h)
2220{
2221 if (w < 0) w = 0;
2222 if (h < 0) h = 0;
2223 if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return;
2224 ee->prop.min.w = w;
2225 ee->prop.min.h = h;
2226 _ecore_evas_x_size_pos_hints_update(ee);
2227}
2228
2229static void
2230_ecore_evas_x_size_max_set(Ecore_Evas *ee, int w, int h)
2231{
2232 if (w < 0) w = 0;
2233 if (h < 0) h = 0;
2234 if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return;
2235 ee->prop.max.w = w;
2236 ee->prop.max.h = h;
2237 _ecore_evas_x_size_pos_hints_update(ee);
2238}
2239
2240static void
2241_ecore_evas_x_size_base_set(Ecore_Evas *ee, int w, int h)
2242{
2243 if (w < 0) w = 0;
2244 if (h < 0) h = 0;
2245 if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return;
2246 ee->prop.base.w = w;
2247 ee->prop.base.h = h;
2248 _ecore_evas_x_size_pos_hints_update(ee);
2249}
2250
2251static void
2252_ecore_evas_x_size_step_set(Ecore_Evas *ee, int w, int h)
2253{
2254 if (w < 1) w = 1;
2255 if (h < 1) h = 1;
2256 if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return;
2257 ee->prop.step.w = w;
2258 ee->prop.step.h = h;
2259 _ecore_evas_x_size_pos_hints_update(ee);
2260}
2261
2262static void
2263_ecore_evas_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2264{
2265 Ecore_Evas *ee;
2266
2267 ee = data;
2268 if (ee) ee->prop.cursor.object = NULL;
2269}
2270
2271static void
2272_ecore_evas_x_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
2273{
2274 int x, y;
2275
2276 if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
2277
2278 if (!obj)
2279 {
2280 ee->prop.cursor.object = NULL;
2281 ee->prop.cursor.layer = 0;
2282 ee->prop.cursor.hot.x = 0;
2283 ee->prop.cursor.hot.y = 0;
2284 ecore_x_window_cursor_show(ee->prop.window, 1);
2285 return;
2286 }
2287
2288 ee->prop.cursor.object = obj;
2289 ee->prop.cursor.layer = layer;
2290 ee->prop.cursor.hot.x = hot_x;
2291 ee->prop.cursor.hot.y = hot_y;
2292
2293 ecore_x_window_cursor_show(ee->prop.window, 0);
2294
2295 evas_pointer_output_xy_get(ee->evas, &x, &y);
2296 evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
2297 evas_object_move(ee->prop.cursor.object,
2298 x - ee->prop.cursor.hot.x,
2299 y - ee->prop.cursor.hot.y);
2300 evas_object_pass_events_set(ee->prop.cursor.object, 1);
2301 if (evas_pointer_inside_get(ee->evas))
2302 evas_object_show(ee->prop.cursor.object);
2303
2304 evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
2305}
2306
2307/*
2308 * @param ee
2309 * @param layer If < 3, @a ee will be put below all other windows.
2310 * If > 5, @a ee will be "always-on-top"
2311 * If = 4, @a ee will be put in the default layer.
2312 * Acceptable values range from 1 to 255 (0 reserved for
2313 * desktop windows)
2314 */
2315static void
2316_ecore_evas_x_layer_set(Ecore_Evas *ee, int layer)
2317{
2318 if (ee->prop.layer == layer) return;
2319
2320 /* FIXME: Should this logic be here? */
2321 if (layer < 1)
2322 layer = 1;
2323 else if (layer > 255)
2324 layer = 255;
2325
2326 ee->prop.layer = layer;
2327 _ecore_evas_x_layer_update(ee);
2328}
2329
2330static void
2331_ecore_evas_x_focus_set(Ecore_Evas *ee, int on __UNUSED__)
2332{
2333 ecore_x_window_focus(ee->prop.window);
2334}
2335
2336static void
2337_ecore_evas_x_iconified_set(Ecore_Evas *ee, int on)
2338{
2339 if (ee->prop.iconified == on) return;
2340 ee->prop.iconified = on;
2341 if (on)
2342 {
2343 ecore_x_icccm_hints_set(ee->prop.window,
2344 1 /* accepts_focus */,
2345 ECORE_X_WINDOW_STATE_HINT_ICONIC /* initial_state */,
2346 0 /* icon_pixmap */,
2347 0 /* icon_mask */,
2348 0 /* icon_window */,
2349 0 /* window_group */,
2350 0 /* is_urgent */);
2351 ecore_x_icccm_iconic_request_send(ee->prop.window, ee->engine.x.win_root);
2352 }
2353 else
2354 {
2355 ecore_x_icccm_hints_set(ee->prop.window,
2356 1 /* accepts_focus */,
2357 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2358 0 /* icon_pixmap */,
2359 0 /* icon_mask */,
2360 0 /* icon_window */,
2361 0 /* window_group */,
2362 0 /* is_urgent */);
2363 ecore_evas_show(ee);
2364 }
2365}
2366
2367static void
2368_ecore_evas_x_borderless_set(Ecore_Evas *ee, int on)
2369{
2370 if (ee->prop.borderless == on) return;
2371 ee->prop.borderless = on;
2372 ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
2373}
2374
2375/* FIXME: This function changes the initial state of the ee
2376 * whilest the iconic function changes the current state! */
2377static void
2378_ecore_evas_x_withdrawn_set(Ecore_Evas *ee, int withdrawn)
2379{
2380 Ecore_X_Window_State_Hint hint;
2381
2382 if (ee->prop.withdrawn == withdrawn) return;
2383
2384 ee->prop.withdrawn = withdrawn;
2385 if (withdrawn)
2386 hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
2387 else
2388 hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
2389
2390 ecore_x_icccm_hints_set(ee->prop.window,
2391 1 /* accepts_focus */,
2392 hint /* initial_state */,
2393 0 /* icon_pixmap */,
2394 0 /* icon_mask */,
2395 0 /* icon_window */,
2396 0 /* window_group */,
2397 0 /* is_urgent */);
2398}
2399
2400static void
2401_ecore_evas_x_sticky_set(Ecore_Evas *ee, int sticky)
2402{
2403 if (ee->prop.sticky == sticky) return;
2404
2405 /* We dont want to set prop.sticky here as it will cause
2406 * the sticky callback not to get called. Its set on the
2407 * property change event.
2408 * ee->prop.sticky = sticky;
2409 */
2410 ee->engine.x.state.sticky = sticky;
2411 if (ee->should_be_visible)
2412 ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root,
2413 ECORE_X_WINDOW_STATE_STICKY, -1, sticky);
2414 else
2415 _ecore_evas_x_state_update(ee);
2416}
2417
2418static void
2419_ecore_evas_x_ignore_events_set(Ecore_Evas *ee, int ignore)
2420{
2421 if (ee->ignore_events == ignore) return;
2422
2423 ee->ignore_events = ignore;
2424 if (ee->prop.window)
2425 ecore_x_window_ignore_set(ee->prop.window, ignore);
2426}
2427
2428/*
2429static void
2430_ecore_evas_x_reinit_win(Ecore_Evas *ee)
2431{
2432 if (!strcmp(ee->driver, "software_x11"))
2433 {
2434#ifdef BUILD_ECORE_EVAS_X11
2435 Evas_Engine_Info_Software_X11 *einfo;
2436
2437 einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
2438 if (einfo)
2439 {
2440 einfo->info.drawable = ee->prop.window;
2441 evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
2442 }
2443#endif
2444 }
2445 else if (!strcmp(ee->driver, "opengl_x11"))
2446 {
2447#ifdef BUILD_ECORE_EVAS_OPENGL_X11
2448 Evas_Engine_Info_GL_X11 *einfo;
2449
2450 einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
2451 if (einfo)
2452 {
2453 einfo->info.drawable = ee->prop.window;
2454 evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
2455 }
2456#endif
2457 }
2458}
2459*/
2460
2461static void
2462_ecore_evas_x_override_set(Ecore_Evas *ee, int on)
2463{
2464 if (ee->prop.override == on) return;
2465 if (ee->should_be_visible) ecore_x_window_hide(ee->prop.window);
2466 ecore_x_window_override_set(ee->prop.window, on);
2467 if (ee->should_be_visible) ecore_x_window_show(ee->prop.window);
2468 if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
2469 ee->prop.override = on;
2470}
2471
2472static void
2473_ecore_evas_x_fullscreen_set(Ecore_Evas *ee, int on)
2474{
2475 if (ee->prop.fullscreen == on) return;
2476
2477 /* FIXME: Detect if WM is EWMH compliant and handle properly if not,
2478 * i.e. reposition, resize, and change borderless hint */
2479 ee->engine.x.state.fullscreen = on;
2480 if (ee->should_be_visible)
2481 ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root,
2482 ECORE_X_WINDOW_STATE_FULLSCREEN, -1, on);
2483 else
2484 _ecore_evas_x_state_update(ee);
2485}
2486
2487static void
2488_ecore_evas_x_avoid_damage_set(Ecore_Evas *ee, int on)
2489{
2490 if (ee->prop.avoid_damage == on) return;
2491 if (!strcmp(ee->driver, "opengl_x11")) return;
2492
2493 if (!strcmp(ee->driver, "software_x11"))
2494 {
2495#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
2496 Evas_Engine_Info_Software_X11 *einfo;
2497
2498 ee->prop.avoid_damage = on;
2499 einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
2500 if (einfo)
2501 {
2502 if (ee->prop.avoid_damage)
2503 {
2504 ee->engine.x.pmap = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, einfo->info.depth);
2505 ee->engine.x.gc = ecore_x_gc_new(ee->engine.x.pmap, 0, NULL);
2506 einfo->info.drawable = ee->engine.x.pmap;
2507 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2508 {
2509 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2510 }
2511 if ((ee->rotation == 90) || (ee->rotation == 270))
2512 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
2513 else
2514 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
2515 if (ee->prop.avoid_damage == ECORE_EVAS_AVOID_DAMAGE_BUILT_IN)
2516 {
2517 ee->engine.x.using_bg_pixmap = 1;
2518 ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2519 ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
2520 }
2521 if (ee->engine.x.direct_resize)
2522 {
2523 /* Turn this off for now
2524 ee->engine.x.using_bg_pixmap = 1;
2525 ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2526 */
2527 }
2528 }
2529 else
2530 {
2531 if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap);
2532 if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc);
2533 if (ee->engine.x.using_bg_pixmap)
2534 {
2535 ecore_x_window_pixmap_set(ee->prop.window, 0);
2536 ee->engine.x.using_bg_pixmap = 0;
2537 ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
2538 }
2539 ee->engine.x.pmap = 0;
2540 ee->engine.x.gc = 0;
2541 einfo->info.drawable = ee->prop.window;
2542 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2543 {
2544 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2545 }
2546 }
2547 }
2548#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
2549 }
2550 else if (!strcmp(ee->driver, "software_16_x11"))
2551 {
2552#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
2553 Evas_Engine_Info_Software_16_X11 *einfo;
2554
2555 ee->prop.avoid_damage = on;
2556 einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
2557 if (einfo)
2558 {
2559 if (ee->prop.avoid_damage)
2560 {
2561 ee->engine.x.pmap = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 16);
2562 ee->engine.x.gc = ecore_x_gc_new(ee->engine.x.pmap, 0, NULL);
2563 einfo->info.drawable = ee->engine.x.pmap;
2564 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2565 {
2566 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2567 }
2568 if ((ee->rotation == 90) || (ee->rotation == 270))
2569 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
2570 else
2571 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
2572 if (ee->engine.x.direct_resize)
2573 {
2574 /* Turn this off for now
2575 ee->engine.x.using_bg_pixmap = 1;
2576 ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2577 */
2578 }
2579 }
2580 else
2581 {
2582 if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap);
2583 if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc);
2584 if (ee->engine.x.using_bg_pixmap)
2585 {
2586 ecore_x_window_pixmap_set(ee->prop.window, 0);
2587 ee->engine.x.using_bg_pixmap = 0;
2588 }
2589 ee->engine.x.pmap = 0;
2590 ee->engine.x.gc = 0;
2591 einfo->info.drawable = ee->prop.window;
2592 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2593 {
2594 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2595 }
2596 }
2597 }
2598#endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
2599 }
2600 else if (!strcmp(ee->driver, "software_8_x11"))
2601 {
2602#if BUILD_ECORE_EVAS_SOFTWARE_8_X11
2603 Evas_Engine_Info_Software_8_X11 *einfo;
2604
2605 ee->prop.avoid_damage = on;
2606 einfo = (Evas_Engine_Info_Software_8_X11 *)evas_engine_info_get(ee->evas);
2607 if (einfo)
2608 {
2609 if (ee->prop.avoid_damage)
2610 {
2611 ee->engine.x.pmap = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, einfo->info.depth);
2612 ee->engine.x.gc = ecore_x_gc_new(ee->engine.x.pmap, 0, NULL);
2613 einfo->info.drawable = ee->engine.x.pmap;
2614 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2615 {
2616 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2617 }
2618 if ((ee->rotation == 90) || (ee->rotation == 270))
2619 evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
2620 else
2621 evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
2622 if (ee->prop.avoid_damage == ECORE_EVAS_AVOID_DAMAGE_BUILT_IN)
2623 {
2624 ee->engine.x.using_bg_pixmap = 1;
2625 ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2626 ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
2627 }
2628 if (ee->engine.x.direct_resize)
2629 {
2630 /* Turn this off for now
2631 ee->engine.x.using_bg_pixmap = 1;
2632 ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2633 */
2634 }
2635 }
2636 else
2637 {
2638 if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap);
2639 if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc);
2640 if (ee->engine.x.using_bg_pixmap)
2641 {
2642 ecore_x_window_pixmap_set(ee->prop.window, 0);
2643 ee->engine.x.using_bg_pixmap = 0;
2644 ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
2645 }
2646 ee->engine.x.pmap = 0;
2647 ee->engine.x.gc = 0;
2648 einfo->info.drawable = ee->prop.window;
2649 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2650 {
2651 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2652 }
2653 }
2654 }
2655#endif /* BUILD_ECORE_EVAS_SOFTWARE_8_X11 */
2656 }
2657}
2658
2659static void
2660_ecore_evas_x_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h)
2661{
2662 if (x) *x = 0;
2663 if (y) *y = 0;
2664 ecore_x_screen_size_get(ecore_x_default_screen_get(), w, h);
2665}
2666
2667int
2668_ecore_evas_x_shutdown(void)
2669{
2670 _ecore_evas_init_count--;
2671 if (_ecore_evas_init_count == 0)
2672 {
2673 unsigned int i;
2674
2675 for (i = 0; i < sizeof(ecore_evas_event_handlers) / sizeof(Ecore_Event_Handler*); i++)
2676 {
2677 if (ecore_evas_event_handlers[i])
2678 ecore_event_handler_del(ecore_evas_event_handlers[i]);
2679 }
2680 ecore_event_evas_shutdown();
2681 }
2682 if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
2683 return _ecore_evas_init_count;
2684}
2685
2686static Ecore_Evas_Engine_Func _ecore_x_engine_func =
2687{
2688 _ecore_evas_x_free,
2689 NULL,
2690 NULL,
2691 NULL,
2692 NULL,
2693 _ecore_evas_x_callback_delete_request_set,
2694 NULL,
2695 NULL,
2696 NULL,
2697 NULL,
2698 NULL,
2699 NULL,
2700 NULL,
2701 NULL,
2702 NULL,
2703 _ecore_evas_x_move,
2704 _ecore_evas_x_managed_move,
2705 _ecore_evas_x_resize,
2706 _ecore_evas_x_move_resize,
2707 _ecore_evas_x_rotation_set,
2708 _ecore_evas_x_shaped_set,
2709 _ecore_evas_x_show,
2710 _ecore_evas_x_hide,
2711 _ecore_evas_x_raise,
2712 _ecore_evas_x_lower,
2713 _ecore_evas_x_activate,
2714 _ecore_evas_x_title_set,
2715 _ecore_evas_x_name_class_set,
2716 _ecore_evas_x_size_min_set,
2717 _ecore_evas_x_size_max_set,
2718 _ecore_evas_x_size_base_set,
2719 _ecore_evas_x_size_step_set,
2720 _ecore_evas_x_object_cursor_set,
2721 _ecore_evas_x_layer_set,
2722 _ecore_evas_x_focus_set,
2723 _ecore_evas_x_iconified_set,
2724 _ecore_evas_x_borderless_set,
2725 _ecore_evas_x_override_set,
2726 NULL,
2727 _ecore_evas_x_fullscreen_set,
2728 _ecore_evas_x_avoid_damage_set,
2729 _ecore_evas_x_withdrawn_set,
2730 _ecore_evas_x_sticky_set,
2731 _ecore_evas_x_ignore_events_set,
2732 _ecore_evas_x_alpha_set,
2733 _ecore_evas_x_transparent_set,
2734
2735 NULL, // render
2736 _ecore_evas_x_screen_geometry_get
2737};
2738#endif /* BUILD_ECORE_EVAS_X11 */
2739
2740/*
2741 * FIXME: there are some round trips. Especially, we can split
2742 * ecore_x_init in 2 functions and suppress some round trips.
2743 */
2744
2745#if defined (BUILD_ECORE_EVAS_SOFTWARE_X11) || defined (BUILD_ECORE_EVAS_OPENGL_X11) || defined (BUILD_ECORE_EVAS_SOFTWARE_16_X11) || defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
2746static void
2747_ecore_evas_x_flush_pre(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__)
2748{
2749 Ecore_Evas *ee = data;
2750
2751 if (ee->no_comp_sync) return;
2752 if (!_ecore_evas_app_comp_sync) return;
2753 if (ee->engine.x.sync_counter)
2754 {
2755 if (ee->engine.x.sync_began)
2756 {
2757 ee->engine.x.sync_val++;
2758 if (!ee->engine.x.sync_cancel)
2759 {
2760 if (!ee->semi_sync)
2761 ecore_x_sync_counter_val_wait(ee->engine.x.sync_counter,
2762 ee->engine.x.sync_val);
2763 }
2764 }
2765 }
2766}
2767
2768static void
2769_ecore_evas_x_flush_post(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__)
2770{
2771 Ecore_Evas *ee = data;
2772
2773 if ((!ee->no_comp_sync) && (_ecore_evas_app_comp_sync))
2774 {
2775 if (ee->engine.x.sync_counter)
2776 {
2777 if (ee->engine.x.sync_began)
2778 {
2779 if (!ee->engine.x.sync_cancel)
2780 {
2781 ecore_x_e_comp_sync_draw_size_done_send
2782 (ee->engine.x.win_root, ee->prop.window, ee->w, ee->h);
2783 }
2784 }
2785 }
2786 }
2787 if (ee->engine.x.netwm_sync_set)
2788 {
2789 ecore_x_sync_counter_2_set(ee->engine.x.netwm_sync_counter,
2790 ee->engine.x.netwm_sync_val_hi,
2791 ee->engine.x.netwm_sync_val_lo);
2792 ee->engine.x.netwm_sync_set = 0;
2793 }
2794}
2795#endif
2796
2797/**
2798 * To be documented.
2799 *
2800 * FIXME: To be fixed.
2801 */
2802#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
2803EAPI Ecore_Evas *
2804ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent,
2805 int x, int y, int w, int h)
2806{
2807 Evas_Engine_Info_Software_X11 *einfo;
2808 Ecore_Evas *ee;
2809 int argb = 0, rmethod;
2810 static int redraw_debug = -1;
2811 char *id = NULL;
2812
2813 rmethod = evas_render_method_lookup("software_x11");
2814 if (!rmethod) return NULL;
2815 if (!ecore_x_init(disp_name)) return NULL;
2816 ee = calloc(1, sizeof(Ecore_Evas));
2817 if (!ee) return NULL;
2818
2819 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
2820
2821 _ecore_evas_x_init();
2822
2823 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
2824
2825 ee->driver = "software_x11";
2826 if (disp_name) ee->name = strdup(disp_name);
2827
2828 if (w < 1) w = 1;
2829 if (h < 1) h = 1;
2830 ee->x = x;
2831 ee->y = y;
2832 ee->w = w;
2833 ee->h = h;
2834 ee->req.x = ee->x;
2835 ee->req.y = ee->y;
2836 ee->req.w = ee->w;
2837 ee->req.h = ee->h;
2838
2839 ee->prop.max.w = 32767;
2840 ee->prop.max.h = 32767;
2841 ee->prop.layer = 4;
2842 ee->prop.request_pos = 0;
2843 ee->prop.sticky = 0;
2844 ee->engine.x.state.sticky = 0;
2845
2846 /* init evas here */
2847 ee->evas = evas_new();
2848 evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE,
2849 _ecore_evas_x_flush_pre, ee);
2850 evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST,
2851 _ecore_evas_x_flush_post, ee);
2852 evas_data_attach_set(ee->evas, ee);
2853 evas_output_method_set(ee->evas, rmethod);
2854 evas_output_size_set(ee->evas, w, h);
2855 evas_output_viewport_set(ee->evas, 0, 0, w, h);
2856
2857 ee->engine.x.win_root = parent;
2858 ee->engine.x.screen_num = 0;
2859
2860 if (parent != 0)
2861 {
2862 ee->engine.x.screen_num = 1; /* FIXME: get real scren # */
2863 /* FIXME: round trip in ecore_x_window_argb_get */
2864 if (ecore_x_window_argb_get(parent))
2865 {
2866 ee->prop.window = ecore_x_window_argb_new(parent, x, y, w, h);
2867 argb = 1;
2868 }
2869 else
2870 ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
2871 }
2872 else
2873 ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
2874 if ((id = getenv("DESKTOP_STARTUP_ID")))
2875 {
2876 ecore_x_netwm_startup_id_set(ee->prop.window, id);
2877 /* NB: on linux this may simply empty the env as opposed to completely
2878 * unset it to being empty - unsure as solartis libc crashes looking
2879 * for the '=' char */
2880// putenv((char*)"DESKTOP_STARTUP_ID=");
2881 }
2882 einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
2883 if (einfo)
2884 {
2885 Ecore_X_Screen *screen;
2886
2887 /* FIXME: this is inefficient as its 1 or more round trips */
2888 screen = ecore_x_default_screen_get();
2889 if (ecore_x_screen_count_get() > 1)
2890 {
2891 Ecore_X_Window *roots;
2892 int num, i;
2893
2894 num = 0;
2895 roots = ecore_x_window_root_list(&num);
2896 if (roots)
2897 {
2898 Ecore_X_Window root;
2899
2900 root = ecore_x_window_root_get(parent);
2901 for (i = 0; i < num; i++)
2902 {
2903 if (root == roots[i])
2904 {
2905 screen = ecore_x_screen_get(i);
2906 break;
2907 }
2908 }
2909 free(roots);
2910 }
2911 }
2912
2913 einfo->info.destination_alpha = argb;
2914
2915 if (redraw_debug < 0)
2916 {
2917 if (getenv("REDRAW_DEBUG"))
2918 redraw_debug = atoi(getenv("REDRAW_DEBUG"));
2919 else
2920 redraw_debug = 0;
2921 }
2922
2923# ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
2924 einfo->info.backend = EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB;
2925 einfo->info.connection = ecore_x_connection_get();
2926 einfo->info.screen = screen;
2927# else
2928 einfo->info.backend = EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB;
2929 einfo->info.connection = ecore_x_display_get();
2930 einfo->info.screen = NULL;
2931# endif
2932 einfo->info.drawable = ee->prop.window;
2933
2934# ifdef EVAS_FRAME_QUEUING
2935 {
2936 char *render_mode;
2937
2938 render_mode = getenv("EVAS_RENDER_MODE");
2939 if ((render_mode) && (!strcmp(render_mode, "non-blocking")))
2940 einfo->render_mode = EVAS_RENDER_MODE_NONBLOCKING;
2941 }
2942# endif
2943
2944 if (argb)
2945 {
2946 Ecore_X_Window_Attributes at;
2947
2948 ecore_x_window_attributes_get(ee->prop.window, &at);
2949 einfo->info.visual = at.visual;
2950 einfo->info.colormap = at.colormap;
2951 einfo->info.depth = at.depth;
2952 einfo->info.destination_alpha = 1;
2953 }
2954 else
2955 {
2956 einfo->info.visual =
2957 ecore_x_default_visual_get(einfo->info.connection, screen);
2958 einfo->info.colormap =
2959 ecore_x_default_colormap_get(einfo->info.connection, screen);
2960 einfo->info.depth =
2961 ecore_x_default_depth_get(einfo->info.connection, screen);
2962 einfo->info.destination_alpha = 0;
2963 }
2964
2965 einfo->info.rotation = 0;
2966 einfo->info.debug = redraw_debug;
2967 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2968 {
2969 ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
2970 ecore_evas_free(ee);
2971 return NULL;
2972 }
2973 }
2974
2975 ecore_x_icccm_hints_set(ee->prop.window,
2976 1 /* accepts_focus */,
2977 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2978 0 /* icon_pixmap */,
2979 0 /* icon_mask */,
2980 0 /* icon_window */,
2981 0 /* window_group */,
2982 0 /* is_urgent */);
2983 _ecore_evas_x_group_leader_set(ee);
2984 ecore_x_window_defaults_set(ee->prop.window);
2985 _ecore_evas_x_protocols_set(ee);
2986 _ecore_evas_x_sync_set(ee);
2987
2988 ee->engine.func->fn_render = _ecore_evas_x_render;
2989 _ecore_evas_register(ee);
2990 ecore_x_input_multi_select(ee->prop.window);
2991 ecore_event_window_register(ee->prop.window, ee, ee->evas,
2992 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
2993 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
2994 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
2995 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
2996 return ee;
2997}
2998#else
2999EAPI Ecore_Evas *
3000ecore_evas_software_x11_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
3001 int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
3002{
3003 return NULL;
3004}
3005#endif
3006
3007/**
3008 * To be documented.
3009 *
3010 * FIXME: To be fixed.
3011 */
3012#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
3013EAPI Ecore_X_Window
3014ecore_evas_software_x11_window_get(const Ecore_Evas *ee)
3015{
3016 return (Ecore_X_Window) ecore_evas_window_get(ee);
3017}
3018#else
3019EAPI Ecore_X_Window
3020ecore_evas_software_x11_window_get(const Ecore_Evas *ee __UNUSED__)
3021{
3022 return 0;
3023}
3024#endif
3025
3026/**
3027 * To be documented.
3028 *
3029 * FIXME: To be fixed.
3030 */
3031#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
3032EAPI void
3033ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee, Eina_Bool on)
3034{
3035 ee->engine.x.direct_resize = on;
3036 if (ee->prop.avoid_damage)
3037 {
3038 if (ee->engine.x.direct_resize)
3039 {
3040/* turn this off for now
3041 ee->engine.x.using_bg_pixmap = 1;
3042 ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
3043 */
3044 }
3045 else
3046 {
3047/* turn this off too- bg pixmap is controlled by avoid damage directly
3048 ee->engine.x.using_bg_pixmap = 0;
3049 ecore_x_window_pixmap_set(ee->prop.window, 0);
3050 ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
3051 */
3052 }
3053 }
3054}
3055#else
3056EAPI void
3057ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee __UNUSED__, Eina_Bool on __UNUSED__)
3058{
3059}
3060#endif
3061
3062/**
3063 * To be documented.
3064 *
3065 * FIXME: To be fixed.
3066 */
3067#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
3068EAPI Eina_Bool
3069ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee)
3070{
3071 return ee->engine.x.direct_resize;
3072}
3073#else
3074EAPI Eina_Bool
3075ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
3076{
3077 return 0;
3078}
3079#endif
3080
3081/**
3082 * To be documented.
3083 *
3084 * FIXME: To be fixed.
3085 */
3086#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
3087EAPI void
3088ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
3089{
3090 Ecore_X_Window *winp;
3091
3092 winp = malloc(sizeof(Ecore_X_Window));
3093 if (winp)
3094 {
3095 *winp = win;
3096 ee->engine.x.win_extra = eina_list_append(ee->engine.x.win_extra, winp);
3097 ecore_x_input_multi_select(win);
3098 ecore_event_window_register(win, ee, ee->evas,
3099 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
3100 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
3101 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
3102 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
3103 }
3104}
3105#else
3106EAPI void
3107ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
3108{
3109}
3110#endif
3111
3112/**
3113 * To be documented.
3114 *
3115 * FIXME: To be fixed.
3116 */
3117#ifdef BUILD_ECORE_EVAS_OPENGL_X11
3118EAPI Ecore_Evas *
3119ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent,
3120 int x, int y, int w, int h)
3121{
3122 return ecore_evas_gl_x11_options_new(disp_name, parent, x, y, w, h, NULL);
3123}
3124
3125EAPI Ecore_Evas *
3126ecore_evas_gl_x11_options_new(const char *disp_name, Ecore_X_Window parent,
3127 int x, int y, int w, int h, const int *opt)
3128{
3129 Ecore_Evas *ee;
3130 int rmethod;
3131 char *id = NULL;
3132
3133 rmethod = evas_render_method_lookup("gl_x11");
3134 if (!rmethod) return NULL;
3135 if (!ecore_x_init(disp_name)) return NULL;
3136 ee = calloc(1, sizeof(Ecore_Evas));
3137 if (!ee) return NULL;
3138
3139 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
3140
3141 _ecore_evas_x_init();
3142
3143 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
3144
3145 ee->driver = "opengl_x11";
3146 if (!getenv("ECORE_EVAS_COMP_NOSEMISYNC"))
3147 ee->semi_sync = 1; // gl engine doesn't need to sync - its whole swaps
3148// ee->no_comp_sync = 1; // gl engine doesn't need to sync - its whole swaps
3149 if (disp_name) ee->name = strdup(disp_name);
3150
3151 if (w < 1) w = 1;
3152 if (h < 1) h = 1;
3153 ee->x = x;
3154 ee->y = y;
3155 ee->w = w;
3156 ee->h = h;
3157 ee->req.x = ee->x;
3158 ee->req.y = ee->y;
3159 ee->req.w = ee->w;
3160 ee->req.h = ee->h;
3161
3162 ee->prop.max.w = 32767;
3163 ee->prop.max.h = 32767;
3164 ee->prop.layer = 4;
3165 ee->prop.request_pos = 0;
3166 ee->prop.sticky = 0;
3167 ee->engine.x.state.sticky = 0;
3168
3169 /* init evas here */
3170 ee->evas = evas_new();
3171 evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
3172 evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
3173 evas_data_attach_set(ee->evas, ee);
3174 evas_output_method_set(ee->evas, rmethod);
3175 evas_output_size_set(ee->evas, w, h);
3176 evas_output_viewport_set(ee->evas, 0, 0, w, h);
3177
3178 if (parent == 0) parent = DefaultRootWindow(ecore_x_display_get());
3179 ee->engine.x.win_root = parent;
3180
3181 if (ee->engine.x.win_root != 0)
3182 {
3183 ee->engine.x.screen_num = 1; /* FIXME: get real scren # */
3184 /* FIXME: round trip in ecore_x_window_argb_get */
3185 if (ecore_x_window_argb_get(ee->engine.x.win_root))
3186 {
3187 ee->prop.window = _ecore_evas_x_gl_window_new
3188 (ee, ee->engine.x.win_root, x, y, w, h, 0, 1, opt);
3189 }
3190 else
3191 ee->prop.window = _ecore_evas_x_gl_window_new
3192 (ee, ee->engine.x.win_root, x, y, w, h, 0, 0, opt);
3193 }
3194 else
3195 ee->prop.window = _ecore_evas_x_gl_window_new
3196 (ee, ee->engine.x.win_root, x, y, w, h, 0, 0, opt);
3197 if (!ee->prop.window)
3198 {
3199 ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
3200 ecore_evas_free(ee);
3201 return NULL;
3202 }
3203 if ((id = getenv("DESKTOP_STARTUP_ID")))
3204 {
3205 ecore_x_netwm_startup_id_set(ee->prop.window, id);
3206 /* NB: on linux this may simply empty the env as opposed to completely
3207 * unset it to being empty - unsure as solartis libc crashes looking
3208 * for the '=' char */
3209// putenv((char*)"DESKTOP_STARTUP_ID=");
3210 }
3211
3212 ecore_x_icccm_hints_set(ee->prop.window,
3213 1 /* accepts_focus */,
3214 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
3215 0 /* icon_pixmap */,
3216 0 /* icon_mask */,
3217 0 /* icon_window */,
3218 0 /* window_group */,
3219 0 /* is_urgent */);
3220 _ecore_evas_x_group_leader_set(ee);
3221 ecore_x_window_defaults_set(ee->prop.window);
3222 _ecore_evas_x_protocols_set(ee);
3223 _ecore_evas_x_sync_set(ee);
3224
3225 ee->engine.func->fn_render = _ecore_evas_x_render;
3226 _ecore_evas_register(ee);
3227 ecore_x_input_multi_select(ee->prop.window);
3228 ecore_event_window_register(ee->prop.window, ee, ee->evas,
3229 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
3230 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
3231 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
3232 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
3233
3234 return ee;
3235}
3236#else
3237EAPI Ecore_Evas *
3238ecore_evas_gl_x11_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
3239 int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
3240{
3241 return NULL;
3242}
3243EAPI Ecore_Evas *
3244ecore_evas_gl_x11_options_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
3245 int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__, const int *opt __UNUSED__)
3246{
3247 return NULL;
3248}
3249#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3250
3251/**
3252 * To be documented.
3253 *
3254 * FIXME: To be fixed.
3255 */
3256#ifdef BUILD_ECORE_EVAS_OPENGL_X11
3257EAPI Ecore_X_Window
3258ecore_evas_gl_x11_window_get(const Ecore_Evas *ee)
3259{
3260 return (Ecore_X_Window) ecore_evas_window_get(ee);
3261}
3262#else
3263EAPI Ecore_X_Window
3264ecore_evas_gl_x11_window_get(const Ecore_Evas *ee __UNUSED__)
3265{
3266 return 0;
3267}
3268#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3269
3270/**
3271 * To be documented.
3272 *
3273 * FIXME: To be fixed.
3274 */
3275#ifdef BUILD_ECORE_EVAS_OPENGL_X11
3276EAPI void
3277ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee, Eina_Bool on)
3278{
3279 ee->engine.x.direct_resize = on;
3280}
3281#else
3282EAPI void
3283ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee __UNUSED__, Eina_Bool on __UNUSED__)
3284{
3285}
3286#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3287
3288/**
3289 * To be documented.
3290 *
3291 * FIXME: To be fixed.
3292 */
3293#ifdef BUILD_ECORE_EVAS_OPENGL_X11
3294EAPI Eina_Bool
3295ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee)
3296{
3297 return ee->engine.x.direct_resize;
3298}
3299#else
3300EAPI Eina_Bool
3301ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
3302{
3303 return 0;
3304}
3305#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3306
3307/**
3308 * To be documented.
3309 *
3310 * FIXME: To be fixed.
3311 */
3312#ifdef BUILD_ECORE_EVAS_OPENGL_X11
3313EAPI void
3314ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
3315{
3316 ecore_evas_software_x11_extra_event_window_add(ee, win);
3317}
3318#else
3319EAPI void
3320ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
3321{
3322}
3323#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3324
3325/**
3326 * To be documented.
3327 *
3328 * FIXME: To be fixed.
3329 */
3330#ifdef BUILD_ECORE_EVAS_OPENGL_X11
3331EAPI void
3332ecore_evas_gl_x11_pre_post_swap_callback_set(const Ecore_Evas *ee, void *data, void (*pre_cb) (void *data, Evas *e), void (*post_cb) (void *data, Evas *e))
3333{
3334 Evas_Engine_Info_GL_X11 *einfo;
3335
3336 if (!(!strcmp(ee->driver, "opengl_x11"))) return;
3337
3338 einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
3339 if (einfo)
3340 {
3341 einfo->callback.pre_swap = pre_cb;
3342 einfo->callback.post_swap = post_cb;
3343 einfo->callback.data = data;
3344 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
3345 {
3346 ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
3347 }
3348 }
3349}
3350#else
3351EAPI void
3352ecore_evas_gl_x11_pre_post_swap_callback_set(const Ecore_Evas *ee __UNUSED__, void *data __UNUSED__, void (*pre_cb) (void *data, Evas *e) __UNUSED__, void (*post_cb) (void *data, Evas *e) __UNUSED__)
3353{
3354 return;
3355}
3356#endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3357
3358/**
3359 * To be documented.
3360 *
3361 * FIXME: To be fixed or maybe removed rather?
3362 */
3363EAPI Ecore_Evas *
3364ecore_evas_xrender_x11_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
3365 int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
3366{
3367 return NULL;
3368}
3369
3370/**
3371 * To be documented.
3372 *
3373 * FIXME: To be fixed or maybe removed rather?
3374 */
3375EAPI Ecore_X_Window
3376ecore_evas_xrender_x11_window_get(const Ecore_Evas *ee __UNUSED__)
3377{
3378 return 0;
3379}
3380
3381/**
3382 * To be documented.
3383 *
3384 * FIXME: To be fixed.
3385 */
3386EAPI void
3387ecore_evas_xrender_x11_direct_resize_set(Ecore_Evas *ee __UNUSED__, Eina_Bool on __UNUSED__)
3388{
3389}
3390
3391/**
3392 * To be documented.
3393 *
3394 * FIXME: To be fixed.
3395 */
3396EAPI Eina_Bool
3397ecore_evas_xrender_x11_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
3398{
3399 return 0;
3400}
3401
3402/**
3403 * To be documented.
3404 *
3405 * FIXME: To be fixed.
3406 */
3407EAPI void
3408ecore_evas_xrender_x11_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
3409{
3410}
3411
3412/**
3413 * To be documented.
3414 *
3415 * FIXME: To be fixed.
3416 */
3417#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
3418EAPI Ecore_Evas *
3419ecore_evas_software_x11_16_new(const char *disp_name, Ecore_X_Window parent,
3420 int x, int y, int w, int h)
3421{
3422 Evas_Engine_Info_Software_16_X11 *einfo;
3423 Ecore_Evas *ee;
3424 int rmethod;
3425 static int redraw_debug = -1;
3426
3427 rmethod = evas_render_method_lookup("software_16_x11");
3428 if (!rmethod) return NULL;
3429 if (!ecore_x_init(disp_name)) return NULL;
3430 ee = calloc(1, sizeof(Ecore_Evas));
3431 if (!ee) return NULL;
3432
3433 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
3434
3435 _ecore_evas_x_init();
3436
3437 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
3438
3439 ee->driver = "software_16_x11";
3440 if (disp_name) ee->name = strdup(disp_name);
3441
3442 if (w < 1) w = 1;
3443 if (h < 1) h = 1;
3444 ee->x = x;
3445 ee->y = y;
3446 ee->w = w;
3447 ee->h = h;
3448 ee->req.x = ee->x;
3449 ee->req.y = ee->y;
3450 ee->req.w = ee->w;
3451 ee->req.h = ee->h;
3452
3453 ee->prop.max.w = 32767;
3454 ee->prop.max.h = 32767;
3455 ee->prop.layer = 4;
3456 ee->prop.request_pos = 0;
3457 ee->prop.sticky = 0;
3458 ee->engine.x.state.sticky = 0;
3459
3460 /* init evas here */
3461 ee->evas = evas_new();
3462 evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
3463 evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
3464 evas_data_attach_set(ee->evas, ee);
3465 evas_output_method_set(ee->evas, rmethod);
3466 evas_output_size_set(ee->evas, w, h);
3467 evas_output_viewport_set(ee->evas, 0, 0, w, h);
3468
3469 ee->engine.x.win_root = parent;
3470 if (parent != 0)
3471 {
3472 /* FIXME: round trip in ecore_x_window_argb_get */
3473 if (ecore_x_window_argb_get(parent))
3474 {
3475 ee->prop.window = ecore_x_window_argb_new(parent, x, y, w, h);
3476 }
3477 else
3478 ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
3479 }
3480 else
3481 ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
3482 if (getenv("DESKTOP_STARTUP_ID"))
3483 {
3484 ecore_x_netwm_startup_id_set(ee->prop.window,
3485 getenv("DESKTOP_STARTUP_ID"));
3486 /* NB: on linux this may simply empty the env as opposed to completely
3487 * unset it to being empty - unsure as solartis libc crashes looking
3488 * for the '=' char */
3489// putenv((char*)"DESKTOP_STARTUP_ID=");
3490 }
3491 einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
3492
3493 if (einfo)
3494 {
3495 if (ScreenCount(ecore_x_display_get()) > 1)
3496 {
3497 Ecore_X_Window *roots;
3498 int num, i;
3499
3500 num = 0;
3501 roots = ecore_x_window_root_list(&num);
3502 if (roots)
3503 {
3504 XWindowAttributes at;
3505
3506 if (XGetWindowAttributes(ecore_x_display_get(),
3507 parent, &at))
3508 {
3509 for (i = 0; i < num; i++)
3510 {
3511 if (at.root == roots[i])
3512 break;
3513 }
3514 }
3515 free(roots);
3516 }
3517 }
3518
3519 if (redraw_debug < 0)
3520 {
3521 if (getenv("REDRAW_DEBUG"))
3522 redraw_debug = atoi(getenv("REDRAW_DEBUG"));
3523 else
3524 redraw_debug = 0;
3525 }
3526 einfo->info.display = ecore_x_display_get();
3527 einfo->info.drawable = ee->prop.window;
3528
3529 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
3530 {
3531 ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
3532 ecore_evas_free(ee);
3533 return NULL;
3534 }
3535 }
3536 else
3537 {
3538 ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
3539 ecore_evas_free(ee);
3540 return NULL;
3541 }
3542
3543 ecore_x_icccm_hints_set(ee->prop.window,
3544 1 /* accepts_focus */,
3545 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
3546 0 /* icon_pixmap */,
3547 0 /* icon_mask */,
3548 0 /* icon_window */,
3549 0 /* window_group */,
3550 0 /* is_urgent */);
3551 _ecore_evas_x_group_leader_set(ee);
3552 ecore_x_window_defaults_set(ee->prop.window);
3553 _ecore_evas_x_protocols_set(ee);
3554 _ecore_evas_x_sync_set(ee);
3555
3556 ee->engine.func->fn_render = _ecore_evas_x_render;
3557 _ecore_evas_register(ee);
3558 ecore_x_input_multi_select(ee->prop.window);
3559 ecore_event_window_register(ee->prop.window, ee, ee->evas,
3560 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
3561 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
3562 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
3563 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
3564 return ee;
3565}
3566#else
3567EAPI Ecore_Evas *
3568ecore_evas_software_x11_16_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
3569 int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
3570{
3571 return NULL;
3572}
3573#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
3574
3575/**
3576 * To be documented.
3577 *
3578 * FIXME: To be fixed.
3579 */
3580#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
3581EAPI Ecore_X_Window
3582ecore_evas_software_x11_16_window_get(const Ecore_Evas *ee)
3583{
3584 return (Ecore_X_Window) ecore_evas_window_get(ee);
3585}
3586#else
3587EAPI Ecore_X_Window
3588ecore_evas_software_x11_16_window_get(const Ecore_Evas *ee __UNUSED__)
3589{
3590 return 0;
3591}
3592#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
3593
3594/**
3595 * To be documented.
3596 *
3597 * FIXME: To be fixed.
3598 */
3599#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
3600EAPI void
3601ecore_evas_software_x11_16_direct_resize_set(Ecore_Evas *ee, Eina_Bool on)
3602{
3603 ee->engine.x.direct_resize = on;
3604 if (ee->prop.avoid_damage)
3605 {
3606 if (ee->engine.x.direct_resize)
3607 {
3608/* turn this off for now
3609 ee->engine.x.using_bg_pixmap = 1;
3610 ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
3611 */
3612 }
3613 else
3614 {
3615/* turn this off too- bg pixmap is controlled by avoid damage directly
3616 ee->engine.x.using_bg_pixmap = 0;
3617 ecore_x_window_pixmap_set(ee->prop.window, 0);
3618 ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
3619 */
3620 }
3621 }
3622}
3623#else
3624EAPI void
3625ecore_evas_software_x11_16_direct_resize_set(Ecore_Evas *ee __UNUSED__, Eina_Bool on __UNUSED__)
3626{
3627}
3628#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
3629
3630/**
3631 * To be documented.
3632 *
3633 * FIXME: To be fixed.
3634 */
3635#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
3636EAPI Eina_Bool
3637ecore_evas_software_x11_16_direct_resize_get(const Ecore_Evas *ee)
3638{
3639 return ee->engine.x.direct_resize;
3640}
3641#else
3642EAPI Eina_Bool
3643ecore_evas_software_x11_16_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
3644{
3645 return 0;
3646}
3647#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
3648
3649/**
3650 * To be documented.
3651 *
3652 * FIXME: To be fixed.
3653 */
3654#if BUILD_ECORE_EVAS_SOFTWARE_16_X11
3655EAPI void
3656ecore_evas_software_x11_16_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
3657{
3658 Ecore_X_Window *winp;
3659
3660 winp = malloc(sizeof(Ecore_X_Window));
3661 if (winp)
3662 {
3663 *winp = win;
3664 ee->engine.x.win_extra = eina_list_append(ee->engine.x.win_extra, winp);
3665 ecore_x_input_multi_select(win);
3666 ecore_event_window_register(win, ee, ee->evas,
3667 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
3668 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
3669 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
3670 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
3671 }
3672}
3673#else
3674EAPI void
3675ecore_evas_software_x11_16_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
3676{
3677}
3678#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
3679
3680
3681/**
3682 * To be documented.
3683 *
3684 * FIXME: To be fixed.
3685 */
3686EAPI Ecore_Evas *
3687ecore_evas_software_x11_8_new(const char *disp_name, Ecore_X_Window parent,
3688 int x, int y, int w, int h)
3689{
3690#if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
3691 Evas_Engine_Info_Software_8_X11 *einfo;
3692 Ecore_Evas *ee;
3693 int argb = 0;
3694 int rmethod;
3695 static int redraw_debug = -1;
3696
3697 rmethod = evas_render_method_lookup("software_8_x11");
3698 if (!rmethod) return NULL;
3699 if (!ecore_x_init(disp_name)) return NULL;
3700 ee = calloc(1, sizeof(Ecore_Evas));
3701 if (!ee) return NULL;
3702
3703 ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
3704
3705 _ecore_evas_x_init();
3706
3707 ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
3708
3709 ee->driver = "software_8_x11";
3710 if (disp_name) ee->name = strdup(disp_name);
3711
3712 if (w < 1) w = 1;
3713 if (h < 1) h = 1;
3714 ee->x = x;
3715 ee->y = y;
3716 ee->w = w;
3717 ee->h = h;
3718 ee->req.x = ee->x;
3719 ee->req.y = ee->y;
3720 ee->req.w = ee->w;
3721 ee->req.h = ee->h;
3722
3723 ee->prop.max.w = 32767;
3724 ee->prop.max.h = 32767;
3725 ee->prop.layer = 4;
3726 ee->prop.request_pos = 0;
3727 ee->prop.sticky = 0;
3728 ee->engine.x.state.sticky = 0;
3729
3730 /* init evas here */
3731 ee->evas = evas_new();
3732 evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
3733 evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
3734 evas_data_attach_set(ee->evas, ee);
3735 evas_output_method_set(ee->evas, rmethod);
3736 evas_output_size_set(ee->evas, w, h);
3737 evas_output_viewport_set(ee->evas, 0, 0, w, h);
3738
3739 ee->engine.x.win_root = parent;
3740 // if (parent != 0)
3741 // {
3742 // /* FIXME: round trip in ecore_x_window_argb_get */
3743 // if (ecore_x_window_argb_get(parent))
3744 // {
3745 // ee->engine.x.win = ecore_x_window_argb_new(parent, x, y, w, h);
3746 // argb = 1;
3747 // }
3748 // else
3749 // ee->engine.x.win = ecore_x_window_new(parent, x, y, w, h);
3750 // }
3751 // else
3752 ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
3753 if (getenv("DESKTOP_STARTUP_ID"))
3754 {
3755 ecore_x_netwm_startup_id_set(ee->prop.window,
3756 getenv("DESKTOP_STARTUP_ID"));
3757 /* NB: on linux this may simply empty the env as opposed to completely
3758 * unset it to being empty - unsure as solartis libc crashes looking
3759 * for the '=' char */
3760 // putenv((char*)"DESKTOP_STARTUP_ID=");
3761 }
3762 einfo = (Evas_Engine_Info_Software_8_X11 *)evas_engine_info_get(ee->evas);
3763 if (einfo)
3764 {
3765 xcb_screen_iterator_t iter;
3766 xcb_screen_t *screen;
3767
3768 /* FIXME: this is inefficient as its a round trip */
3769 //einfo->info.backend = 1;
3770 screen = ecore_x_default_screen_get();
3771 iter = xcb_setup_roots_iterator (xcb_get_setup (ecore_x_connection_get()));
3772 if (iter.rem > 1)
3773 {
3774 xcb_get_geometry_cookie_t cookie;
3775 xcb_get_geometry_reply_t *reply;
3776 Ecore_X_Window *roots;
3777 int num;
3778 uint8_t i;
3779
3780 num = 0;
3781 cookie = xcb_get_geometry_unchecked(ecore_x_connection_get(), parent);
3782 roots = ecore_x_window_root_list(&num);
3783 if (roots)
3784 {
3785 reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
3786
3787 if (reply)
3788 {
3789 for (i = 0; i < num; xcb_screen_next (&iter), i++)
3790 {
3791 if (reply->root == roots[i])
3792 {
3793 screen = iter.data;
3794 break;
3795 }
3796 }
3797 free(reply);
3798 }
3799 free(roots);
3800 }
3801 else
3802 {
3803 reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
3804 if (reply) free(reply);
3805 }
3806 }
3807
3808 if (redraw_debug < 0)
3809 {
3810 if (getenv("REDRAW_DEBUG"))
3811 redraw_debug = atoi(getenv("REDRAW_DEBUG"));
3812 else
3813 redraw_debug = 0;
3814 }
3815 einfo->info.connection = ecore_x_connection_get();
3816 einfo->info.screen = screen;
3817 einfo->info.drawable = ee->prop.window;
3818 if (argb)
3819 {
3820 /* FIXME: round trip */
3821 xcb_get_geometry_cookie_t cookie_geom;
3822 xcb_get_window_attributes_cookie_t cookie_attr;
3823 xcb_get_geometry_reply_t *reply_geom;
3824 xcb_get_window_attributes_reply_t *reply_attr;
3825
3826 cookie_geom = xcb_get_geometry_unchecked(ecore_x_connection_get(), ee->prop.window);
3827 cookie_attr = xcb_get_window_attributes_unchecked(ecore_x_connection_get(), ee->prop.window);
3828
3829 reply_geom = xcb_get_geometry_reply(ecore_x_connection_get(), cookie_geom, NULL);
3830 reply_attr = xcb_get_window_attributes_reply(ecore_x_connection_get(), cookie_attr, NULL);
3831 if (reply_attr && reply_geom)
3832 {
3833 einfo->info.visual = xcb_visualtype_get(ecore_x_default_screen_get(), reply_attr->visual);
3834 einfo->info.colormap = reply_attr->colormap;
3835 einfo->info.depth = reply_geom->depth;
3836 einfo->info.destination_alpha = 1;
3837 free(reply_geom);
3838 free(reply_attr);
3839 }
3840 }
3841 else
3842 {
3843 xcb_screen_t *screen;
3844
3845 screen = ecore_x_default_screen_get();
3846 einfo->info.visual = xcb_visualtype_get(screen, screen->root_visual);
3847 einfo->info.colormap = screen->default_colormap;
3848 einfo->info.depth = screen->root_depth;
3849 einfo->info.destination_alpha = 0;
3850 }
3851 einfo->info.rotation = 0;
3852 einfo->info.debug = redraw_debug;
3853 if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
3854 {
3855 ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
3856 ecore_evas_free(ee);
3857 return NULL;
3858 }
3859 }
3860 else
3861 {
3862 ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
3863 ecore_evas_free(ee);
3864 return NULL;
3865 }
3866
3867 ecore_x_icccm_hints_set(ee->prop.window,
3868 1 /* accepts_focus */,
3869 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
3870 0 /* icon_pixmap */,
3871 0 /* icon_mask */,
3872 0 /* icon_window */,
3873 0 /* window_group */,
3874 0 /* is_urgent */);
3875 _ecore_evas_x_group_leader_set(ee);
3876 ecore_x_window_defaults_set(ee->prop.window);
3877 _ecore_evas_x_protocols_set(ee);
3878 _ecore_evas_x_sync_set(ee);
3879
3880 ee->engine.func->fn_render = _ecore_evas_x_render;
3881 _ecore_evas_register(ee);
3882 ecore_x_input_multi_select(ee->prop.window);
3883 ecore_event_window_register(ee->prop.window, ee, ee->evas,
3884 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
3885 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
3886 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
3887 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
3888
3889 return ee;
3890#else
3891 return NULL;
3892 (void)(disp_name);
3893 (void)(parent);
3894 (void)(x);
3895 (void)(y);
3896 (void)(w);
3897 (void)(h);
3898#endif /* ! BUILD_ECORE_EVAS_SOFTWARE_8_X11 */
3899}
3900
3901/**
3902 * To be documented.
3903 *
3904 * FIXME: To be fixed.
3905 */
3906EAPI Ecore_X_Window
3907ecore_evas_software_x11_8_window_get(const Ecore_Evas *ee)
3908{
3909#if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
3910 return (Ecore_X_Window) ecore_evas_window_get(ee);
3911#else
3912 return 0;
3913 (void)(ee);
3914#endif
3915}
3916
3917/**
3918 * To be documented.
3919 *
3920 * FIXME: To be fixed.
3921 */
3922EAPI Ecore_X_Window
3923ecore_evas_software_x11_8_subwindow_get(const Ecore_Evas *ee)
3924{
3925#if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
3926 return (Ecore_X_Window) ecore_evas_window_get(ee);
3927#else
3928 return 0;
3929 (void)(ee);
3930#endif
3931}
3932
3933/**
3934 * To be documented.
3935 *
3936 * FIXME: To be fixed.
3937 */
3938EAPI void
3939ecore_evas_software_x11_8_direct_resize_set(Ecore_Evas *ee, Eina_Bool on)
3940{
3941#if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
3942 ee->engine.x.direct_resize = on;
3943 if (ee->prop.avoid_damage)
3944 {
3945 if (ee->engine.x.direct_resize)
3946 {
3947 /* turn this off for now
3948 ee->engine.x.using_bg_pixmap = 1;
3949 ecore_x_window_pixmap_set(ee->engine.x.win, ee->engine.x.pmap);
3950 */
3951 }
3952 else
3953 {
3954 /* turn this off too- bg pixmap is controlled by avoid damage directly
3955 ee->engine.x.using_bg_pixmap = 0;
3956 ecore_x_window_pixmap_set(ee->engine.x.win, 0);
3957 ecore_x_window_area_expose(ee->engine.x.win, 0, 0, ee->w, ee->h);
3958 */
3959 }
3960 }
3961#else
3962 return;
3963 (void)(ee);
3964 (void)(on);
3965#endif
3966}
3967
3968/**
3969 * To be documented.
3970 *
3971 * FIXME: To be fixed.
3972 */
3973EAPI Eina_Bool
3974ecore_evas_software_x11_8_direct_resize_get(const Ecore_Evas *ee)
3975{
3976#if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
3977 return ee->engine.x.direct_resize;
3978#else
3979 return 0;
3980 (void)(ee);
3981#endif
3982}
3983
3984/**
3985 * To be documented.
3986 *
3987 * FIXME: To be fixed.
3988 */
3989EAPI void
3990ecore_evas_software_x11_8_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
3991{
3992#if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
3993 Ecore_X_Window *winp;
3994
3995 winp = malloc(sizeof(Ecore_X_Window));
3996 if (winp)
3997 {
3998 *winp = win;
3999 ee->engine.x.win_extra = eina_list_append(ee->engine.x.win_extra, winp);
4000 ecore_x_input_multi_select(win);
4001 ecore_event_window_register(win, ee, ee->evas,
4002 (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
4003 (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
4004 (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
4005 (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
4006 }
4007#else
4008 return;
4009 (void)(ee);
4010 (void)(win);
4011#endif
4012}
4013
4014EAPI void
4015ecore_evas_x11_leader_set(Ecore_Evas *ee, Ecore_X_Window win)
4016{
4017#ifdef BUILD_ECORE_EVAS_X11
4018 _ecore_evas_x_group_leader_unset(ee);
4019 ee->engine.x.leader = win;
4020 _ecore_evas_x_group_leader_update(ee);
4021#else
4022 return;
4023 ee = NULL;
4024 win = 0;
4025#endif
4026}
4027
4028EAPI Ecore_X_Window
4029ecore_evas_x11_leader_get(Ecore_Evas *ee)
4030{
4031#ifdef BUILD_ECORE_EVAS_X11
4032 return ee->engine.x.leader;
4033#else
4034 return 0;
4035 ee = NULL;
4036#endif
4037}
4038
4039EAPI void
4040ecore_evas_x11_leader_default_set(Ecore_Evas *ee)
4041{
4042#ifdef BUILD_ECORE_EVAS_X11
4043 _ecore_evas_x_group_leader_unset(ee);
4044 _ecore_evas_x_group_leader_set(ee);
4045#else
4046 return;
4047 ee = NULL;
4048#endif
4049}
4050
4051#ifdef BUILD_ECORE_EVAS_X11
4052static Eina_Bool
4053_ecore_evas_x11_convert_rectangle_with_angle(Ecore_Evas *ee, Ecore_X_Rectangle *dst_rect, Ecore_X_Rectangle *src_rect)
4054{
4055 if ((!src_rect) || (!dst_rect)) return 0;
4056
4057 if (ee->rotation == 0)
4058 {
4059 dst_rect->x = src_rect->x;
4060 dst_rect->y = src_rect->y;
4061 dst_rect->width = src_rect->width;
4062 dst_rect->height = src_rect->height;
4063 }
4064 else if (ee->rotation == 90)
4065 {
4066 dst_rect->x = src_rect->y;
4067 dst_rect->y = ee->req.h - src_rect->x - src_rect->width;
4068 dst_rect->width = src_rect->height;
4069 dst_rect->height = src_rect->width;
4070 }
4071 else if (ee->rotation == 180)
4072 {
4073 dst_rect->x = ee->req.w - src_rect->x - src_rect->width;
4074 dst_rect->y = ee->req.h - src_rect->y - src_rect->height;
4075 dst_rect->width = src_rect->width;
4076 dst_rect->height = src_rect->height;
4077 }
4078 else if (ee->rotation == 270)
4079 {
4080 dst_rect->x = ee->req.w - src_rect->y - src_rect->height;
4081 dst_rect->y = src_rect->x;
4082 dst_rect->width = src_rect->height;
4083 dst_rect->height = src_rect->width;
4084 }
4085 else
4086 {
4087 return 0;
4088 }
4089
4090 return 1;
4091}
4092#endif
4093
4094EAPI void
4095ecore_evas_x11_shape_input_rectangle_set(Ecore_Evas *ee, int x, int y, int w, int h)
4096{
4097#ifdef BUILD_ECORE_EVAS_X11
4098 Eina_Bool ret;
4099 Ecore_X_Rectangle src_rect;
4100 Ecore_X_Rectangle dst_rect;
4101
4102 if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
4103 {
4104 ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
4105 "ecore_evas_x11_shape_input_rectangle_set");
4106 return;
4107 }
4108
4109 src_rect.x = x;
4110 src_rect.y = y;
4111 src_rect.width = w;
4112 src_rect.height = h;
4113
4114 dst_rect.x = 0;
4115 dst_rect.y = 0;
4116 dst_rect.width = 0;
4117 dst_rect.height = 0;
4118
4119 ret = _ecore_evas_x11_convert_rectangle_with_angle(ee, &dst_rect, &src_rect);
4120
4121 if (!ee->engine.x.win_shaped_input)
4122 ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root,
4123 0, 0, 1, 1);
4124
4125 if (ret)
4126 ecore_x_window_shape_input_rectangle_set(ee->engine.x.win_shaped_input,
4127 dst_rect.x, dst_rect.y,
4128 dst_rect.width, dst_rect.height);
4129#else
4130 return;
4131 ee = NULL;
4132 x = 0;
4133 y = 0;
4134 w = 0;
4135 h = 0;
4136#endif
4137}
4138
4139EAPI void
4140ecore_evas_x11_shape_input_rectangle_add(Ecore_Evas *ee, int x, int y, int w, int h)
4141{
4142#ifdef BUILD_ECORE_EVAS_X11
4143 Eina_Bool ret;
4144 Ecore_X_Rectangle src_rect;
4145 Ecore_X_Rectangle dst_rect;
4146
4147 if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
4148 {
4149 ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
4150 "ecore_evas_x11_shape_input_rectangle_add");
4151 return;
4152 }
4153
4154 src_rect.x = x;
4155 src_rect.y = y;
4156 src_rect.width = w;
4157 src_rect.height = h;
4158
4159 dst_rect.x = 0;
4160 dst_rect.y = 0;
4161 dst_rect.width = 0;
4162 dst_rect.height = 0;
4163
4164 ret = _ecore_evas_x11_convert_rectangle_with_angle(ee, &dst_rect, &src_rect);
4165
4166 if (!ee->engine.x.win_shaped_input)
4167 ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root,
4168 0, 0, 1, 1);
4169
4170 if (ret)
4171 ecore_x_window_shape_input_rectangle_add(ee->engine.x.win_shaped_input,
4172 dst_rect.x, dst_rect.y,
4173 dst_rect.width, dst_rect.height);
4174#else
4175 return;
4176 ee = NULL;
4177 x = 0;
4178 y = 0;
4179 w = 0;
4180 h = 0;
4181#endif
4182}
4183
4184EAPI void
4185ecore_evas_x11_shape_input_rectangle_subtract(Ecore_Evas *ee, int x, int y, int w, int h)
4186{
4187#ifdef BUILD_ECORE_EVAS_X11
4188 Eina_Bool ret;
4189 Ecore_X_Rectangle src_rect;
4190 Ecore_X_Rectangle dst_rect;
4191
4192 if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
4193 {
4194 ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
4195 "ecore_evas_x11_shape_input_rectangle_subtract");
4196 return;
4197 }
4198
4199 src_rect.x = x;
4200 src_rect.y = y;
4201 src_rect.width = w;
4202 src_rect.height = h;
4203
4204 dst_rect.x = 0;
4205 dst_rect.y = 0;
4206 dst_rect.width = 0;
4207 dst_rect.height = 0;
4208
4209 ret = _ecore_evas_x11_convert_rectangle_with_angle(ee, &dst_rect, &src_rect);
4210
4211 if (!ee->engine.x.win_shaped_input)
4212 ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root,
4213 0, 0, 1, 1);
4214
4215 if (ret)
4216 ecore_x_window_shape_input_rectangle_subtract(ee->engine.x.win_shaped_input,
4217 dst_rect.x, dst_rect.y,
4218 dst_rect.width, dst_rect.height);
4219#else
4220 return;
4221 ee = NULL;
4222 x = 0;
4223 y = 0;
4224 w = 0;
4225 h = 0;
4226#endif
4227}
4228
4229EAPI void
4230ecore_evas_x11_shape_input_empty(Ecore_Evas *ee)
4231{
4232#ifdef BUILD_ECORE_EVAS_X11
4233 if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
4234 {
4235 ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
4236 "ecore_evas_x11_shape_input_empty");
4237 return;
4238 }
4239
4240 if (!ee->engine.x.win_shaped_input)
4241 ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, 0, 0, 1, 1);
4242
4243 ecore_x_window_shape_input_rectangle_set(ee->engine.x.win_shaped_input, 0, 0, 0, 0);
4244#else
4245 return;
4246 ee = NULL;
4247#endif
4248}
4249
4250EAPI void
4251ecore_evas_x11_shape_input_reset(Ecore_Evas *ee)
4252{
4253#ifdef BUILD_ECORE_EVAS_X11
4254 if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
4255 {
4256 ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
4257 "ecore_evas_x11_shape_input_reset");
4258 return;
4259 }
4260
4261 if (!ee->engine.x.win_shaped_input)
4262 ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, 0, 0, 1, 1);
4263
4264 ecore_x_window_shape_input_rectangle_set(ee->engine.x.win_shaped_input, 0, 0, 65535, 65535);
4265#else
4266 return;
4267 ee = NULL;
4268#endif
4269}
4270
4271EAPI void
4272ecore_evas_x11_shape_input_apply(Ecore_Evas *ee)
4273{
4274#ifdef BUILD_ECORE_EVAS_X11
4275 if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
4276 {
4277 ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
4278 "ecore_evas_x11_shape_input_apply");
4279 return;
4280 }
4281
4282 if (!ee->engine.x.win_shaped_input) return;
4283
4284 ecore_x_window_shape_input_window_set(ee->prop.window, ee->engine.x.win_shaped_input);
4285#else
4286 return;
4287 ee = NULL;
4288#endif
4289}