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