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