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