fix sync issue in 1 special event re-order case. booo!
[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 static void
1517 _ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize)
1518 {
1519    if (ee->rotation == rotation) return;
1520    if (!strcmp(ee->driver, "xrender_x11")) return;
1521    if (!strcmp(ee->driver, "opengl_x11"))
1522      {
1523 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
1524         Evas_Engine_Info_GL_X11 *einfo;
1525
1526         einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
1527         if (!einfo) return;
1528         einfo->info.rotation = rotation;
1529         _ecore_evas_x_rotation_set_internal
1530           (ee, rotation, resize, (Evas_Engine_Info *)einfo);
1531 #endif /* BUILD_ECORE_EVAS_OPENGL_X11 */
1532      }
1533    else if (!strcmp(ee->driver, "software_x11"))
1534      {
1535 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
1536         Evas_Engine_Info_Software_X11 *einfo;
1537
1538         einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
1539         if (!einfo) return;
1540         einfo->info.rotation = rotation;
1541         _ecore_evas_x_rotation_set_internal
1542           (ee, rotation, resize, (Evas_Engine_Info *)einfo);
1543 #endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
1544      }
1545    else if (!strcmp(ee->driver,  "software_16_x11"))
1546      {
1547 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
1548         Evas_Engine_Info_Software_16_X11 *einfo;
1549
1550         einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
1551         if (!einfo) return;
1552         einfo->info.rotation = rotation;
1553         _ecore_evas_x_rotation_set_internal
1554           (ee, rotation, resize, (Evas_Engine_Info *)einfo);
1555 #endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
1556      }
1557    else if (!strcmp(ee->driver,  "software_8_x11"))
1558      {
1559 #if BUILD_ECORE_EVAS_SOFTWARE_8_X11
1560         Evas_Engine_Info_Software_8_X11 *einfo;
1561
1562         einfo = (Evas_Engine_Info_Software_8_X11 *)evas_engine_info_get(ee->evas);
1563         if (!einfo) return;
1564         einfo->info.rotation = rotation;
1565         _ecore_evas_x_rotation_set_internal
1566            (ee, rotation, resize, (Evas_Engine_Info *)einfo);
1567 #endif /* BUILD_ECORE_EVAS_SOFTWARE_8_X11 */
1568      }
1569 }
1570
1571 static void
1572 _ecore_evas_x_shaped_set(Ecore_Evas *ee, int shaped)
1573 {
1574    if (((ee->shaped) && (shaped)) || ((!ee->shaped) && (!shaped)))
1575      return;
1576    if (!strcmp(ee->driver, "opengl_x11")) return;
1577    if (!strcmp(ee->driver, "software_x11"))
1578      {
1579 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
1580         Evas_Engine_Info_Software_X11 *einfo;
1581
1582         einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
1583         ee->shaped = shaped;
1584         if (einfo)
1585           {
1586              if (ee->shaped)
1587                {
1588                   unsigned int    foreground;
1589                   Ecore_X_GC      gc;
1590
1591                   if (!ee->engine.x.mask)
1592                     ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
1593                   foreground = 0;
1594                   gc = ecore_x_gc_new(ee->engine.x.mask,
1595                                       ECORE_X_GC_VALUE_MASK_FOREGROUND,
1596                                       &foreground);
1597                   ecore_x_drawable_rectangle_fill(ee->engine.x.mask, gc,
1598                                                   0, 0, ee->w, ee->h);
1599                   ecore_x_gc_free(gc);
1600                   einfo->info.mask = ee->engine.x.mask;
1601                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1602                     {
1603                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1604                     }
1605                   evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1606                   ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1607                }
1608              else
1609                {
1610                   if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1611                   ee->engine.x.mask = 0;
1612                   einfo->info.mask = 0;
1613                   evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
1614                   ecore_x_window_shape_mask_set(ee->prop.window, 0);
1615                   ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1616                }
1617           }
1618 #endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
1619      }
1620    else if (!strcmp(ee->driver, "xrender_x11"))
1621      {
1622 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
1623         Evas_Engine_Info_XRender_X11 *einfo;
1624
1625         ee->shaped = shaped;
1626         einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
1627         if (einfo)
1628           {
1629              if (ee->shaped)
1630                {
1631                   unsigned int    foreground;
1632                   Ecore_X_GC      gc;
1633
1634                   if (!ee->engine.x.mask)
1635                     ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
1636                   foreground = 0;
1637                   gc = ecore_x_gc_new(ee->engine.x.mask,
1638                                       ECORE_X_GC_VALUE_MASK_FOREGROUND,
1639                                       &foreground);
1640                   ecore_x_drawable_rectangle_fill(ee->engine.x.mask, gc,
1641                                                   0, 0, ee->w, ee->h);
1642                   ecore_x_gc_free(gc);
1643                   einfo->info.mask = ee->engine.x.mask;
1644                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1645                     {
1646                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1647                     }
1648                   evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1649                   ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1650                }
1651              else
1652                {
1653                   if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1654                   ee->engine.x.mask = 0;
1655                   einfo->info.mask = 0;
1656                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1657                     {
1658                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1659                     }
1660                   ecore_x_window_shape_mask_set(ee->prop.window, 0);
1661                   ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1662                }
1663           }
1664 #endif /* BUILD_ECORE_EVAS_XRENDER_X11 || BUILD_ECORE_EVAS_XRENDER_XCB */
1665      }
1666    else if (!strcmp(ee->driver, "software_16_x11"))
1667      {
1668 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
1669 # if 0 /* XXX no shaped window support for software_16_x11 */
1670         Evas_Engine_Info_Software_16_X11 *einfo;
1671
1672         einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
1673         ee->shaped = shaped;
1674         if (einfo)
1675           {
1676              if (ee->shaped)
1677                {
1678                   GC gc;
1679                   XGCValues gcv;
1680
1681                   ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
1682                   einfo->info.mask = ee->engine.x.mask;
1683                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1684                     {
1685                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1686                     }
1687                   evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1688                }
1689              else
1690                {
1691                   if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1692                   ee->engine.x.mask = 0;
1693                   einfo->info.mask = 0;
1694                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1695                     {
1696                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1697                     }
1698                   ecore_x_window_shape_mask_set(ee->prop.window, 0);
1699                }
1700           }
1701 # endif /* XXX no shaped window support for software_16_x11 */
1702 #endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
1703      }
1704    if (!strcmp(ee->driver, "software_8_x11"))
1705      {
1706 #if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
1707         Evas_Engine_Info_Software_8_X11 *einfo;
1708
1709         einfo = (Evas_Engine_Info_Software_8_X11 *)evas_engine_info_get(ee->evas);
1710         ee->shaped = shaped;
1711         if (einfo)
1712           {
1713              if (ee->shaped)
1714                {
1715                   unsigned int    foreground;
1716                   Ecore_X_GC      gc;
1717
1718                   if (!ee->engine.x.mask)
1719                     ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
1720                   foreground = 0;
1721                   gc = ecore_x_gc_new(ee->engine.x.mask,
1722                                       ECORE_X_GC_VALUE_MASK_FOREGROUND,
1723                                       &foreground);
1724                   ecore_x_drawable_rectangle_fill(ee->engine.x.mask, gc,
1725                                                   0, 0, ee->w, ee->h);
1726                   ecore_x_gc_free(gc);
1727                   einfo->info.mask = ee->engine.x.mask;
1728                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1729                     {
1730                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1731                     }
1732                   evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1733                   ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1734                }
1735              else
1736                {
1737                   if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1738                   ee->engine.x.mask = 0;
1739                   einfo->info.mask = 0;
1740                   evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
1741                   ecore_x_window_shape_mask_set(ee->prop.window, 0);
1742                   ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1743                }
1744           }
1745 #endif /* BUILD_ECORE_EVAS_SOFTWARE_8_X11 */
1746      }
1747 }
1748
1749 /* FIXME, round trip */
1750 static void
1751 _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha)
1752 {
1753 # ifdef HAVE_ECORE_X_XCB
1754    xcb_get_geometry_cookie_t          cookie_geom;
1755    xcb_get_window_attributes_cookie_t cookie_attr;
1756    xcb_get_geometry_reply_t          *reply_geom;
1757    xcb_get_window_attributes_reply_t *reply_attr;
1758 #else
1759    XWindowAttributes att;
1760 #endif /* ! HAVE_ECORE_X_XCB */
1761
1762    if (((ee->alpha) && (alpha)) || ((!ee->alpha) && (!alpha)))
1763      return;
1764
1765    if (!strcmp(ee->driver, "software_x11"))
1766      {
1767 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
1768         Evas_Engine_Info_Software_X11 *einfo;
1769
1770         einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
1771         if (!einfo) return;
1772
1773         if (!ecore_x_composite_query()) return;
1774
1775         ee->shaped = 0;
1776         ee->alpha = alpha;
1777         ecore_x_window_free(ee->prop.window);
1778         ecore_event_window_unregister(ee->prop.window);
1779         if (ee->alpha)
1780           {
1781              if (ee->prop.override)
1782                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);
1783              else
1784                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);
1785              if (!ee->engine.x.mask)
1786                ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
1787           }
1788         else
1789           {
1790              if (ee->prop.override)
1791                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);
1792              else
1793                ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
1794              if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1795              ee->engine.x.mask = 0;
1796              ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1797           }
1798
1799         einfo->info.destination_alpha = alpha;
1800
1801 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
1802         cookie_geom = xcb_get_geometry_unchecked(ecore_x_connection_get(), ee->prop.window);
1803         cookie_attr = xcb_get_window_attributes_unchecked(ecore_x_connection_get(), ee->prop.window);
1804
1805         reply_geom = xcb_get_geometry_reply(ecore_x_connection_get(), cookie_geom, NULL);
1806         reply_attr = xcb_get_window_attributes_reply(ecore_x_connection_get(), cookie_attr, NULL);
1807         einfo->info.visual = xcb_visualtype_get(ecore_x_default_screen_get(), reply_attr->visual);
1808         einfo->info.colormap = reply_attr->colormap;
1809         einfo->info.depth = reply_geom->depth;
1810         free(reply_geom);
1811         free(reply_attr);
1812 # else
1813         XGetWindowAttributes(ecore_x_display_get(), ee->prop.window, &att);
1814         einfo->info.visual = att.visual;
1815         einfo->info.colormap = att.colormap;
1816         einfo->info.depth = att.depth;
1817 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
1818
1819 //      if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1820 //      ee->engine.x.mask = 0;
1821         einfo->info.mask = ee->engine.x.mask;
1822         einfo->info.drawable = ee->prop.window;
1823         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1824           {
1825              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1826           }
1827         evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
1828         ecore_x_window_shape_mask_set(ee->prop.window, 0);
1829         ecore_x_input_multi_select(ee->prop.window);
1830         ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
1831         if (ee->prop.borderless)
1832           ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
1833         if (ee->visible) ecore_x_window_show(ee->prop.window);
1834         if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
1835         if (ee->prop.title)
1836           {
1837              ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
1838              ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
1839           }
1840         ecore_x_icccm_hints_set(ee->prop.window,
1841                                 1 /* accepts_focus */,
1842                                 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
1843                                 0 /* icon_pixmap */,
1844                                 0 /* icon_mask */,
1845                                 0 /* icon_window */,
1846                                 0 /* window_group */,
1847                                 0 /* is_urgent */);
1848         _ecore_evas_x_protocols_set(ee);
1849         _ecore_evas_x_sync_set(ee);
1850 #endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
1851         if (getenv("DESKTOP_STARTUP_ID"))
1852           {
1853              ecore_x_netwm_startup_id_set(ee->prop.window,
1854                                           getenv("DESKTOP_STARTUP_ID"));
1855              /* NB: on linux this may simply empty the env as opposed to completely
1856               * unset it to being empty - unsure as solartis libc crashes looking
1857               * for the '=' char */
1858              // putenv((char*)"DESKTOP_STARTUP_ID=");
1859           }
1860      }
1861    else if (!strcmp(ee->driver, "opengl_x11"))
1862      {
1863 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
1864         Evas_Engine_Info_GL_X11 *einfo;
1865
1866         einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
1867         if (!einfo) return;
1868
1869         if (!ecore_x_composite_query()) return;
1870
1871         ee->shaped = 0;
1872         ee->alpha = alpha;
1873         ecore_x_window_free(ee->prop.window);
1874         ecore_event_window_unregister(ee->prop.window);
1875         ee->prop.window = 0;
1876         
1877         einfo->info.destination_alpha = alpha;
1878         
1879         if (ee->engine.x.win_root != 0)
1880           {
1881              /* FIXME: round trip in ecore_x_window_argb_get */
1882              if (ecore_x_window_argb_get(ee->engine.x.win_root))
1883                {
1884                   ee->prop.window = _ecore_evas_x_gl_window_new
1885                     (ee, ee->engine.x.win_root, 
1886                      ee->req.x, ee->req.y, ee->req.w, ee->req.h,
1887                      ee->prop.override, 1, NULL);
1888                }
1889              else
1890                ee->prop.window = _ecore_evas_x_gl_window_new
1891                (ee, ee->engine.x.win_root,
1892                 ee->req.x, ee->req.y, ee->req.w, ee->req.h,
1893                 ee->prop.override, ee->alpha, NULL);
1894           }
1895         else
1896           ee->prop.window = _ecore_evas_x_gl_window_new
1897           (ee, ee->engine.x.win_root, 
1898            ee->req.x, ee->req.y, ee->req.w, ee->req.h,
1899            ee->prop.override, ee->alpha, NULL);
1900         if (!ee->prop.window)
1901           {
1902              return;
1903           }
1904 /*        
1905         if (ee->alpha)
1906           {
1907              if (ee->prop.override)
1908                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);
1909              else
1910                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);
1911              if (!ee->engine.x.mask)
1912                ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
1913           }
1914         else
1915           {
1916              if (ee->prop.override)
1917                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);
1918              else
1919                ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
1920              if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1921              ee->engine.x.mask = 0;
1922              ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1923           }
1924  */
1925
1926         XGetWindowAttributes(ecore_x_display_get(), ee->prop.window, &att);
1927         einfo->info.visual = att.visual;
1928         einfo->info.colormap = att.colormap;
1929         einfo->info.depth = att.depth;
1930
1931 //      if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1932 //      ee->engine.x.mask = 0;
1933 //      einfo->info.mask = ee->engine.x.mask;
1934         einfo->info.drawable = ee->prop.window;
1935         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1936           {
1937              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1938           }
1939         evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
1940 //      ecore_x_window_shape_mask_set(ee->prop.window, 0);
1941         ecore_x_input_multi_select(ee->prop.window);
1942         ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
1943         if (ee->prop.borderless)
1944           ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
1945         if (ee->visible) ecore_x_window_show(ee->prop.window);
1946         if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
1947         if (ee->prop.title)
1948           {
1949              ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
1950              ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
1951           }
1952         ecore_x_icccm_hints_set(ee->prop.window,
1953                                 1 /* accepts_focus */,
1954                                 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
1955                                 0 /* icon_pixmap */,
1956                                 0 /* icon_mask */,
1957                                 0 /* icon_window */,
1958                                 0 /* window_group */,
1959                                 0 /* is_urgent */);
1960         _ecore_evas_x_protocols_set(ee);
1961         _ecore_evas_x_sync_set(ee);
1962 #endif /* BUILD_ECORE_EVAS_OPENGL_X11 */
1963         if (getenv("DESKTOP_STARTUP_ID"))
1964           {
1965              ecore_x_netwm_startup_id_set(ee->prop.window,
1966                                           getenv("DESKTOP_STARTUP_ID"));
1967              /* NB: on linux this may simply empty the env as opposed to completely
1968               * unset it to being empty - unsure as solartis libc crashes looking
1969               * for the '=' char */
1970              // putenv((char*)"DESKTOP_STARTUP_ID=");
1971           }
1972      }
1973    else if (!strcmp(ee->driver, "xrender_x11"))
1974      {
1975 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
1976         Evas_Engine_Info_XRender_X11 *einfo;
1977
1978         einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
1979         if (!einfo) return;
1980         if (!ecore_x_composite_query()) return;
1981
1982         ee->shaped = 0;
1983         ee->alpha = alpha;
1984         ecore_x_window_free(ee->prop.window);
1985         ecore_event_window_unregister(ee->prop.window);
1986         if (ee->alpha)
1987           {
1988              if (ee->prop.override)
1989                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);
1990              else
1991                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);
1992              if (!ee->engine.x.mask)
1993                ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
1994           }
1995         else
1996           {
1997              if (ee->prop.override)
1998                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);
1999              else
2000                ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
2001              if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
2002              ee->engine.x.mask = 0;
2003              ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
2004           }
2005
2006         einfo->info.destination_alpha = alpha;
2007
2008 # ifdef BUILD_ECORE_EVAS_XRENDER_XCB
2009         cookie_attr = xcb_get_window_attributes_unchecked(ecore_x_connection_get(), ee->prop.window);
2010         reply_attr = xcb_get_window_attributes_reply(ecore_x_connection_get(), cookie_attr, NULL);
2011
2012         einfo->info.visual = reply_attr->visual;
2013         free(reply_attr);
2014 # else
2015         XGetWindowAttributes(ecore_x_display_get(), ee->prop.window, &att);
2016         einfo->info.visual = att.visual;
2017 # endif /* ! BUILD_ECORE_EVAS_XRENDER_XCB */
2018
2019 //      if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
2020 //      ee->engine.x.mask = 0;
2021         einfo->info.mask = ee->engine.x.mask;
2022         einfo->info.drawable = ee->prop.window;
2023         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2024           {
2025              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2026           }
2027         evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
2028         ecore_x_window_shape_mask_set(ee->prop.window, 0);
2029         ecore_x_input_multi_select(ee->prop.window);
2030         ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
2031         if (ee->prop.borderless)
2032           ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
2033         if (ee->visible) ecore_x_window_show(ee->prop.window);
2034         if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
2035         if (ee->prop.title)
2036           {
2037              ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
2038              ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
2039           }
2040         ecore_x_icccm_hints_set(ee->prop.window,
2041                                 1 /* accepts_focus */,
2042                                 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2043                                 0 /* icon_pixmap */,
2044                                 0 /* icon_mask */,
2045                                 0 /* icon_window */,
2046                                 0 /* window_group */,
2047                                 0 /* is_urgent */);
2048         _ecore_evas_x_protocols_set(ee);
2049         _ecore_evas_x_sync_set(ee);
2050 #endif /* BUILD_ECORE_EVAS_XRENDER_X11 || BUILD_ECORE_EVAS_XRENDER_XCB */
2051         if (getenv("DESKTOP_STARTUP_ID"))
2052           {
2053              ecore_x_netwm_startup_id_set(ee->prop.window,
2054                                           getenv("DESKTOP_STARTUP_ID"));
2055              /* NB: on linux this may simply empty the env as opposed to completely
2056               * unset it to being empty - unsure as solartis libc crashes looking
2057               * for the '=' char */
2058              // putenv((char*)"DESKTOP_STARTUP_ID=");
2059           }
2060      }
2061    else if (!strcmp(ee->driver, "software_16_x11"))
2062      {
2063 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
2064         Evas_Engine_Info_Software_16_X11 *einfo;
2065
2066         einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
2067         if (!einfo) return;
2068
2069         ee->shaped = 0;
2070         ee->alpha = alpha;
2071         ecore_x_window_free(ee->prop.window);
2072         ecore_event_window_unregister(ee->prop.window);
2073         if (ee->alpha)
2074           {
2075              if (ee->prop.override)
2076                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);
2077              else
2078                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);
2079              if (!ee->engine.x.mask)
2080                ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
2081           }
2082         else
2083           {
2084              if (ee->prop.override)
2085                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);
2086              else
2087                ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
2088              if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
2089              ee->engine.x.mask = 0;
2090              ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
2091           }
2092
2093 # if 0 /* XXX no alpha window support for software_16_x11 */
2094         einfo->info.destination_alpha = alpha;
2095 # endif /* XXX no alpha window support for software_16_x11 */
2096
2097 # if 0 /* XXX no shaped window support for software_16_x11 */
2098 //      if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
2099 //      ee->engine.x.mask = 0;
2100         einfo->info.mask = ee->engine.x.mask;
2101 # endif /* XXX no shaped window support for software_16_x11 */
2102
2103         einfo->info.drawable = ee->prop.window;
2104         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2105           {
2106              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2107           }
2108         evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
2109         ecore_x_window_shape_mask_set(ee->prop.window, 0);
2110         ecore_x_input_multi_select(ee->prop.window);
2111         ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
2112         if (ee->prop.borderless)
2113           ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
2114         if (ee->visible) ecore_x_window_show(ee->prop.window);
2115         if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
2116         if (ee->prop.title)
2117           {
2118              ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
2119              ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
2120           }
2121         ecore_x_icccm_hints_set(ee->prop.window,
2122                                 1 /* accepts_focus */,
2123                                 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2124                                 0 /* icon_pixmap */,
2125                                 0 /* icon_mask */,
2126                                 0 /* icon_window */,
2127                                 0 /* window_group */,
2128                                 0 /* is_urgent */);
2129         _ecore_evas_x_protocols_set(ee);
2130         _ecore_evas_x_sync_set(ee);
2131 #endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
2132         if (getenv("DESKTOP_STARTUP_ID"))
2133           {
2134              ecore_x_netwm_startup_id_set(ee->prop.window,
2135                                           getenv("DESKTOP_STARTUP_ID"));
2136              /* NB: on linux this may simply empty the env as opposed to completely
2137               * unset it to being empty - unsure as solartis libc crashes looking
2138               * for the '=' char */
2139              // putenv((char*)"DESKTOP_STARTUP_ID=");
2140           }
2141      }
2142    else if (!strcmp(ee->driver, "software_8_x11"))
2143      {
2144 #if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
2145         Evas_Engine_Info_Software_8_X11 *einfo;
2146
2147         einfo = (Evas_Engine_Info_Software_8_X11 *)evas_engine_info_get(ee->evas);
2148         if (!einfo) return;
2149
2150         ee->shaped = 0;
2151         ee->alpha = alpha;
2152         ecore_x_window_free(ee->prop.window);
2153         ecore_event_window_unregister(ee->prop.window);
2154         if (ee->alpha)
2155           {
2156              if (ee->prop.override)
2157                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);
2158              else
2159                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);
2160              if (!ee->engine.x.mask)
2161                ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
2162           }
2163         else
2164           {
2165              if (ee->prop.override)
2166                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);
2167              else
2168                ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
2169              if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
2170              ee->engine.x.mask = 0;
2171              ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
2172           }
2173
2174         einfo->info.destination_alpha = alpha;
2175
2176         cookie_geom = xcb_get_geometry_unchecked(ecore_x_connection_get(), ee->prop.window);
2177         cookie_attr = xcb_get_window_attributes_unchecked(ecore_x_connection_get(), ee->prop.window);
2178
2179         reply_geom = xcb_get_geometry_reply(ecore_x_connection_get(), cookie_geom, NULL);
2180         reply_attr = xcb_get_window_attributes_reply(ecore_x_connection_get(), cookie_attr, NULL);
2181         einfo->info.visual = xcb_visualtype_get(ecore_x_default_screen_get(), reply_attr->visual);
2182         einfo->info.colormap = reply_attr->colormap;
2183         einfo->info.depth = reply_geom->depth;
2184         free(reply_geom);
2185         free(reply_attr);
2186
2187 //      if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
2188 //      ee->engine.x.mask = 0;
2189         einfo->info.mask = ee->engine.x.mask;
2190         einfo->info.drawable = ee->prop.window;
2191         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2192           {
2193              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2194           }
2195         evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
2196         ecore_x_window_shape_mask_set(ee->prop.window, 0);
2197         ecore_x_input_multi_select(ee->prop.window);
2198         ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
2199         if (ee->prop.borderless)
2200           ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
2201         if (ee->visible) ecore_x_window_show(ee->prop.window);
2202         if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
2203         if (ee->prop.title)
2204           {
2205              ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
2206              ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
2207           }
2208         ecore_x_icccm_hints_set(ee->prop.window,
2209                                 1 /* accepts_focus */,
2210                                 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2211                                 0 /* icon_pixmap */,
2212                                 0 /* icon_mask */,
2213                                 0 /* icon_window */,
2214                                 0 /* window_group */,
2215                                 0 /* is_urgent */);
2216         _ecore_evas_x_protocols_set(ee);
2217         _ecore_evas_x_sync_set(ee);
2218
2219         if (getenv("DESKTOP_STARTUP_ID"))
2220           {
2221              ecore_x_netwm_startup_id_set(ee->prop.window,
2222                                           getenv("DESKTOP_STARTUP_ID"));
2223              /* NB: on linux this may simply empty the env as opposed to completely
2224               * unset it to being empty - unsure as solartis libc crashes looking
2225               * for the '=' char */
2226              // putenv((char*)"DESKTOP_STARTUP_ID=");
2227           }
2228 #endif /* BUILD_ECORE_EVAS_SOFTWARE_8_X11 */
2229      }
2230 }
2231
2232 static void
2233 _ecore_evas_x_transparent_set(Ecore_Evas *ee, int transparent)
2234 {
2235    if (((ee->transparent) && (transparent)) || 
2236        ((!ee->transparent) && (!transparent)))
2237      return;
2238
2239    if (!strcmp(ee->driver, "software_x11"))
2240      {
2241 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
2242         Evas_Engine_Info_Software_X11 *einfo;
2243
2244         einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
2245         if (!einfo) return;
2246
2247         ee->transparent = transparent;
2248         einfo->info.destination_alpha = transparent;
2249         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2250           {
2251              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2252           }
2253         evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
2254 #endif        
2255      }
2256 }
2257 #endif /* BUILD_ECORE_EVAS_X11 */
2258
2259 #ifdef BUILD_ECORE_EVAS_X11
2260 static void
2261 _ecore_evas_x_show(Ecore_Evas *ee)
2262 {
2263    ee->should_be_visible = 1;
2264    if (ee->prop.avoid_damage)
2265      _ecore_evas_x_render(ee);
2266    ecore_x_window_show(ee->prop.window);
2267    if (ee->prop.fullscreen)
2268      ecore_x_window_focus(ee->prop.window);
2269 }
2270
2271 static void
2272 _ecore_evas_x_hide(Ecore_Evas *ee)
2273 {
2274    ecore_x_window_hide(ee->prop.window);
2275    ee->should_be_visible = 0;
2276 }
2277
2278 static void
2279 _ecore_evas_x_raise(Ecore_Evas *ee)
2280 {
2281    if (!ee->prop.fullscreen)
2282      ecore_x_window_raise(ee->prop.window);
2283    else
2284      ecore_x_window_raise(ee->prop.window);
2285 }
2286
2287 static void
2288 _ecore_evas_x_lower(Ecore_Evas *ee)
2289 {
2290    if (!ee->prop.fullscreen)
2291      ecore_x_window_lower(ee->prop.window);
2292    else
2293      ecore_x_window_lower(ee->prop.window);
2294 }
2295
2296 static void
2297 _ecore_evas_x_activate(Ecore_Evas *ee)
2298 {
2299    ecore_x_netwm_client_active_request(ee->engine.x.win_root,
2300                                        ee->prop.window, 2, 0);
2301 }
2302
2303 static void
2304 _ecore_evas_x_title_set(Ecore_Evas *ee, const char *t)
2305 {
2306    if (ee->prop.title) free(ee->prop.title);
2307    ee->prop.title = NULL;
2308    if (t) ee->prop.title = strdup(t);
2309    ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
2310    ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
2311 }
2312
2313 static void
2314 _ecore_evas_x_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
2315 {
2316    if (ee->prop.name) free(ee->prop.name);
2317    if (ee->prop.clas) free(ee->prop.clas);
2318    ee->prop.name = NULL;
2319    ee->prop.clas = NULL;
2320    if (n) ee->prop.name = strdup(n);
2321    if (c) ee->prop.clas = strdup(c);
2322    ecore_x_icccm_name_class_set(ee->prop.window, ee->prop.name, ee->prop.clas);
2323 }
2324
2325 static void
2326 _ecore_evas_x_size_min_set(Ecore_Evas *ee, int w, int h)
2327 {
2328    if (w < 0) w = 0;
2329    if (h < 0) h = 0;
2330    if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return;
2331    ee->prop.min.w = w;
2332    ee->prop.min.h = h;
2333    _ecore_evas_x_size_pos_hints_update(ee);
2334 }
2335
2336 static void
2337 _ecore_evas_x_size_max_set(Ecore_Evas *ee, int w, int h)
2338 {
2339    if (w < 0) w = 0;
2340    if (h < 0) h = 0;
2341    if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return;
2342    ee->prop.max.w = w;
2343    ee->prop.max.h = h;
2344    _ecore_evas_x_size_pos_hints_update(ee);
2345 }
2346
2347 static void
2348 _ecore_evas_x_size_base_set(Ecore_Evas *ee, int w, int h)
2349 {
2350    if (w < 0) w = 0;
2351    if (h < 0) h = 0;
2352    if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return;
2353    ee->prop.base.w = w;
2354    ee->prop.base.h = h;
2355    _ecore_evas_x_size_pos_hints_update(ee);
2356 }
2357
2358 static void
2359 _ecore_evas_x_size_step_set(Ecore_Evas *ee, int w, int h)
2360 {
2361    if (w < 1) w = 1;
2362    if (h < 1) h = 1;
2363    if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return;
2364    ee->prop.step.w = w;
2365    ee->prop.step.h = h;
2366    _ecore_evas_x_size_pos_hints_update(ee);
2367 }
2368
2369 static void
2370 _ecore_evas_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2371 {
2372    Ecore_Evas *ee;
2373
2374    ee = data;
2375    if (ee)
2376      ee->prop.cursor.object = NULL;
2377 }
2378
2379 static void
2380 _ecore_evas_x_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
2381 {
2382    int x, y;
2383
2384    if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
2385
2386    if (!obj)
2387      {
2388         ee->prop.cursor.object = NULL;
2389         ee->prop.cursor.layer = 0;
2390         ee->prop.cursor.hot.x = 0;
2391         ee->prop.cursor.hot.y = 0;
2392         ecore_x_window_cursor_show(ee->prop.window, 1);
2393         return;
2394      }
2395
2396    ee->prop.cursor.object = obj;
2397    ee->prop.cursor.layer = layer;
2398    ee->prop.cursor.hot.x = hot_x;
2399    ee->prop.cursor.hot.y = hot_y;
2400
2401    ecore_x_window_cursor_show(ee->prop.window, 0);
2402
2403    evas_pointer_output_xy_get(ee->evas, &x, &y);
2404    evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
2405    evas_object_move(ee->prop.cursor.object,
2406                     x - ee->prop.cursor.hot.x,
2407                     y - ee->prop.cursor.hot.y);
2408    evas_object_pass_events_set(ee->prop.cursor.object, 1);
2409    if (evas_pointer_inside_get(ee->evas))
2410      evas_object_show(ee->prop.cursor.object);
2411
2412    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
2413 }
2414
2415 /*
2416  * @param ee
2417  * @param layer If < 3, @a ee will be put below all other windows.
2418  *              If > 5, @a ee will be "always-on-top"
2419  *              If = 4, @a ee will be put in the default layer.
2420  *              Acceptable values range from 1 to 255 (0 reserved for
2421  *              desktop windows)
2422  */
2423 static void
2424 _ecore_evas_x_layer_set(Ecore_Evas *ee, int layer)
2425 {
2426    if (ee->prop.layer == layer) return;
2427
2428    /* FIXME: Should this logic be here? */
2429    if (layer < 1)
2430      layer = 1;
2431    else if (layer > 255)
2432      layer = 255;
2433
2434    ee->prop.layer = layer;
2435    _ecore_evas_x_layer_update(ee);
2436 }
2437
2438 static void
2439 _ecore_evas_x_focus_set(Ecore_Evas *ee, int on __UNUSED__)
2440 {
2441    ecore_x_window_focus(ee->prop.window);
2442 }
2443
2444 static void
2445 _ecore_evas_x_iconified_set(Ecore_Evas *ee, int on)
2446 {
2447 //   if (((ee->prop.iconified) && (on)) ||
2448 //       ((!ee->prop.iconified) && (!on))) return;
2449    ee->prop.iconified = on;
2450    if (on)
2451      {
2452         ecore_x_icccm_hints_set(ee->prop.window,
2453                                 1 /* accepts_focus */,
2454                                 ECORE_X_WINDOW_STATE_HINT_ICONIC /* initial_state */,
2455                                 0 /* icon_pixmap */,
2456                                 0 /* icon_mask */,
2457                                 0 /* icon_window */,
2458                                 0 /* window_group */,
2459                                 0 /* is_urgent */);
2460         ecore_x_icccm_iconic_request_send(ee->prop.window, ee->engine.x.win_root);
2461      }
2462    else
2463      {
2464         ecore_x_icccm_hints_set(ee->prop.window,
2465                                 1 /* accepts_focus */,
2466                                 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2467                                 0 /* icon_pixmap */,
2468                                 0 /* icon_mask */,
2469                                 0 /* icon_window */,
2470                                 0 /* window_group */,
2471                                 0 /* is_urgent */);
2472         ecore_evas_show(ee);
2473      }
2474 }
2475
2476 static void
2477 _ecore_evas_x_borderless_set(Ecore_Evas *ee, int on)
2478 {
2479    if (((ee->prop.borderless) && (on)) ||
2480        ((!ee->prop.borderless) && (!on))) return;
2481    ee->prop.borderless = on;
2482    ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
2483 }
2484
2485 /* FIXME: This function changes the initial state of the ee
2486  * whilest the iconic function changes the current state! */
2487 static void
2488 _ecore_evas_x_withdrawn_set(Ecore_Evas *ee, int withdrawn)
2489 {
2490    Ecore_X_Window_State_Hint hint;
2491
2492    if ((ee->prop.withdrawn && withdrawn) ||
2493       (!ee->prop.withdrawn && !withdrawn)) return;
2494
2495    ee->prop.withdrawn = withdrawn;
2496    if (withdrawn)
2497      hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
2498    else
2499      hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
2500
2501    ecore_x_icccm_hints_set(ee->prop.window,
2502                            1 /* accepts_focus */,
2503                            hint /* initial_state */,
2504                            0 /* icon_pixmap */,
2505                            0 /* icon_mask */,
2506                            0 /* icon_window */,
2507                            0 /* window_group */,
2508                            0 /* is_urgent */);
2509 }
2510
2511 static void
2512 _ecore_evas_x_sticky_set(Ecore_Evas *ee, int sticky)
2513 {
2514    if ((ee->prop.sticky && sticky) ||
2515       (!ee->prop.sticky && !sticky)) return;
2516
2517    /* We dont want to set prop.sticky here as it will cause
2518     * the sticky callback not to get called. Its set on the
2519     * property change event.
2520     * ee->prop.sticky = sticky;
2521     */
2522    ee->engine.x.state.sticky = sticky;
2523    if (ee->should_be_visible)
2524      ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root,
2525                                       ECORE_X_WINDOW_STATE_STICKY, -1, sticky);
2526    else
2527      _ecore_evas_x_state_update(ee);
2528 }
2529
2530 static void
2531 _ecore_evas_x_ignore_events_set(Ecore_Evas *ee, int ignore)
2532 {
2533    if ((ee->ignore_events && ignore) ||
2534        (!ee->ignore_events && !ignore)) return;
2535
2536    if (ignore)
2537      {
2538         ee->ignore_events = 1;
2539         if (ee->prop.window)
2540           ecore_x_window_ignore_set(ee->prop.window, 1);
2541      }
2542    else
2543      {
2544         ee->ignore_events = 0;
2545         if (ee->prop.window)
2546           ecore_x_window_ignore_set(ee->prop.window, 0);
2547      }
2548 }
2549
2550 /*
2551 static void
2552 _ecore_evas_x_reinit_win(Ecore_Evas *ee)
2553 {
2554    if (!strcmp(ee->driver, "software_x11"))
2555      {
2556 #ifdef BUILD_ECORE_EVAS_X11
2557         Evas_Engine_Info_Software_X11 *einfo;
2558
2559         einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
2560         if (einfo)
2561           {
2562              einfo->info.drawable = ee->prop.window;
2563              evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
2564           }
2565 #endif
2566      }
2567    else if (!strcmp(ee->driver, "xrender_x11"))
2568      {
2569 #ifdef BUILD_ECORE_EVAS_XRENDER_X11
2570         Evas_Engine_Info_XRender_X11 *einfo;
2571
2572         einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
2573         if (einfo)
2574           {
2575              einfo->info.drawable = ee->prop.window;
2576              evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
2577           }
2578 #endif
2579      }
2580    else if (!strcmp(ee->driver, "opengl_x11"))
2581      {
2582 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
2583         Evas_Engine_Info_GL_X11 *einfo;
2584
2585         einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
2586         if (einfo)
2587           {
2588              einfo->info.drawable = ee->prop.window;
2589              evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
2590           }
2591 #endif
2592      }
2593 }
2594 */
2595
2596 static void
2597 _ecore_evas_x_override_set(Ecore_Evas *ee, int on)
2598 {
2599    if (((ee->prop.override) && (on)) ||
2600        ((!ee->prop.override) && (!on))) return;
2601    ecore_x_window_hide(ee->prop.window);
2602    ecore_x_window_override_set(ee->prop.window, on);
2603    if (ee->visible) ecore_x_window_show(ee->prop.window);
2604    if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
2605    ee->prop.override = on;
2606 }
2607
2608 static void
2609 _ecore_evas_x_fullscreen_set(Ecore_Evas *ee, int on)
2610 {
2611    if ((ee->prop.fullscreen && on) ||
2612       (!ee->prop.fullscreen && !on)) return;
2613
2614    /* FIXME: Detect if WM is EWMH compliant and handle properly if not,
2615     * i.e. reposition, resize, and change borderless hint */
2616    ee->engine.x.state.fullscreen = on;
2617    if (ee->should_be_visible)
2618      ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root,
2619                                       ECORE_X_WINDOW_STATE_FULLSCREEN, -1, on);
2620    else
2621      _ecore_evas_x_state_update(ee);
2622 }
2623
2624 static void
2625 _ecore_evas_x_avoid_damage_set(Ecore_Evas *ee, int on)
2626 {
2627    if (ee->prop.avoid_damage == on) return;
2628    if (!strcmp(ee->driver, "opengl_x11")) return;
2629    if (!strcmp(ee->driver, "xrender_x11")) return;
2630
2631    if (!strcmp(ee->driver, "software_x11"))
2632      {
2633 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
2634         Evas_Engine_Info_Software_X11 *einfo;
2635
2636         ee->prop.avoid_damage = on;
2637         einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
2638         if (einfo)
2639           {
2640              if (ee->prop.avoid_damage)
2641                {
2642                   ee->engine.x.pmap = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, einfo->info.depth);
2643                   ee->engine.x.gc = ecore_x_gc_new(ee->engine.x.pmap, 0, NULL);
2644                   einfo->info.drawable = ee->engine.x.pmap;
2645                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2646                     {
2647                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2648                     }
2649                   if ((ee->rotation == 90) || (ee->rotation == 270))
2650                     evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
2651                   else
2652                     evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
2653                   if (ee->prop.avoid_damage == ECORE_EVAS_AVOID_DAMAGE_BUILT_IN)
2654                     {
2655                        ee->engine.x.using_bg_pixmap = 1;
2656                        ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2657                        ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
2658                     }
2659                   if (ee->engine.x.direct_resize)
2660                     {
2661                        /* Turn this off for now
2662                           ee->engine.x.using_bg_pixmap = 1;
2663                           ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2664                        */
2665                     }
2666                }
2667              else
2668                {
2669                   if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap);
2670                   if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc);
2671                   if (ee->engine.x.using_bg_pixmap)
2672                     {
2673                        ecore_x_window_pixmap_set(ee->prop.window, 0);
2674                        ee->engine.x.using_bg_pixmap = 0;
2675                        ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
2676                     }
2677                   ee->engine.x.pmap = 0;
2678                   ee->engine.x.gc = 0;
2679                   einfo->info.drawable = ee->prop.window;
2680                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2681                     {
2682                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2683                     }
2684                }
2685           }
2686 #endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
2687      }
2688    else if (!strcmp(ee->driver, "software_16_x11"))
2689      {
2690 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
2691         Evas_Engine_Info_Software_16_X11 *einfo;
2692         ee->prop.avoid_damage = on;
2693
2694         einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
2695         if (einfo)
2696           {
2697              if (ee->prop.avoid_damage)
2698                {
2699                   ee->engine.x.pmap = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 16);
2700                   ee->engine.x.gc = ecore_x_gc_new(ee->engine.x.pmap, 0, NULL);
2701                   einfo->info.drawable = ee->engine.x.pmap;
2702                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2703                     {
2704                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2705                     }
2706                   if ((ee->rotation == 90) || (ee->rotation == 270))
2707                     evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
2708                   else
2709                     evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
2710                   if (ee->engine.x.direct_resize)
2711                     {
2712                        /* Turn this off for now
2713                           ee->engine.x.using_bg_pixmap = 1;
2714                           ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2715                        */
2716                     }
2717                }
2718              else
2719                {
2720                   if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap);
2721                   if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc);
2722                   if (ee->engine.x.using_bg_pixmap)
2723                     {
2724                        ecore_x_window_pixmap_set(ee->prop.window, 0);
2725                        ee->engine.x.using_bg_pixmap = 0;
2726                     }
2727                   ee->engine.x.pmap = 0;
2728                   ee->engine.x.gc = 0;
2729                   einfo->info.drawable = ee->prop.window;
2730                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2731                     {
2732                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2733                     }
2734                }
2735           }
2736 #endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
2737      }
2738    else if (!strcmp(ee->driver, "software_8_x11"))
2739      {
2740 #if BUILD_ECORE_EVAS_SOFTWARE_8_X11
2741         Evas_Engine_Info_Software_8_X11 *einfo;
2742
2743         ee->prop.avoid_damage = on;
2744         einfo = (Evas_Engine_Info_Software_8_X11 *)evas_engine_info_get(ee->evas);
2745         if (einfo)
2746           {
2747              if (ee->prop.avoid_damage)
2748                {
2749                   ee->engine.x.pmap = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, einfo->info.depth);
2750                   ee->engine.x.gc = ecore_x_gc_new(ee->engine.x.pmap, 0, NULL);
2751                   einfo->info.drawable = ee->engine.x.pmap;
2752                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2753                     {
2754                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2755                     }
2756                   if ((ee->rotation == 90) || (ee->rotation == 270))
2757                     evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
2758                   else
2759                     evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
2760                   if (ee->prop.avoid_damage == ECORE_EVAS_AVOID_DAMAGE_BUILT_IN)
2761                     {
2762                        ee->engine.x.using_bg_pixmap = 1;
2763                        ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2764                        ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
2765                     }
2766                   if (ee->engine.x.direct_resize)
2767                     {
2768                        /* Turn this off for now
2769                           ee->engine.x.using_bg_pixmap = 1;
2770                           ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2771                        */
2772                     }
2773                }
2774              else
2775                {
2776                   if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap);
2777                   if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc);
2778                   if (ee->engine.x.using_bg_pixmap)
2779                     {
2780                        ecore_x_window_pixmap_set(ee->prop.window, 0);
2781                        ee->engine.x.using_bg_pixmap = 0;
2782                        ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
2783                     }
2784                   ee->engine.x.pmap = 0;
2785                   ee->engine.x.gc = 0;
2786                   einfo->info.drawable = ee->prop.window;
2787                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2788                     {
2789                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2790                     }
2791                }
2792           }
2793 #endif /* BUILD_ECORE_EVAS_SOFTWARE_8_X11 */
2794      }
2795 }
2796
2797 int
2798 _ecore_evas_x_shutdown(void)
2799 {
2800    _ecore_evas_init_count--;
2801    if (_ecore_evas_init_count == 0)
2802      {
2803         unsigned int i;
2804
2805         for (i = 0; i < sizeof(ecore_evas_event_handlers) / sizeof(Ecore_Event_Handler*); i++)
2806           {
2807              if (ecore_evas_event_handlers[i])
2808                ecore_event_handler_del(ecore_evas_event_handlers[i]);
2809           }
2810         ecore_event_evas_shutdown();
2811      }
2812    if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
2813    return _ecore_evas_init_count;
2814 }
2815
2816 static Ecore_Evas_Engine_Func _ecore_x_engine_func =
2817 {
2818    _ecore_evas_x_free,
2819      NULL,
2820      NULL,
2821      NULL,
2822      NULL,
2823      _ecore_evas_x_callback_delete_request_set,
2824      NULL,
2825      NULL,
2826      NULL,
2827      NULL,
2828      NULL,
2829      NULL,
2830      NULL,
2831      NULL,
2832      NULL,
2833      _ecore_evas_x_move,
2834      _ecore_evas_x_managed_move,
2835      _ecore_evas_x_resize,
2836      _ecore_evas_x_move_resize,
2837      _ecore_evas_x_rotation_set,
2838      _ecore_evas_x_shaped_set,
2839      _ecore_evas_x_show,
2840      _ecore_evas_x_hide,
2841      _ecore_evas_x_raise,
2842      _ecore_evas_x_lower,
2843      _ecore_evas_x_activate,
2844      _ecore_evas_x_title_set,
2845      _ecore_evas_x_name_class_set,
2846      _ecore_evas_x_size_min_set,
2847      _ecore_evas_x_size_max_set,
2848      _ecore_evas_x_size_base_set,
2849      _ecore_evas_x_size_step_set,
2850      _ecore_evas_x_object_cursor_set,
2851      _ecore_evas_x_layer_set,
2852      _ecore_evas_x_focus_set,
2853      _ecore_evas_x_iconified_set,
2854      _ecore_evas_x_borderless_set,
2855      _ecore_evas_x_override_set,
2856      NULL,
2857      _ecore_evas_x_fullscreen_set,
2858      _ecore_evas_x_avoid_damage_set,
2859      _ecore_evas_x_withdrawn_set,
2860      _ecore_evas_x_sticky_set,
2861      _ecore_evas_x_ignore_events_set,
2862      _ecore_evas_x_alpha_set,
2863      _ecore_evas_x_transparent_set,
2864      
2865      NULL // render
2866 };
2867 #endif /* BUILD_ECORE_EVAS_X11 */
2868
2869 /*
2870  * FIXME: there are some round trips. Especially, we can split
2871  * ecore_x_init in 2 functions and supress some round trips.
2872  */
2873
2874 #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)
2875 static void
2876 _ecore_evas_x_flush_pre(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__)
2877 {
2878    Ecore_Evas *ee = data;
2879
2880    if (ee->no_comp_sync) return;
2881    if (!_ecore_evas_app_comp_sync) return;
2882    if (ee->engine.x.sync_counter)
2883      {
2884         if (ee->engine.x.sync_began)
2885           {
2886              ee->engine.x.sync_val++;
2887              if (!ee->engine.x.sync_cancel)
2888                {
2889                   ecore_x_sync_counter_val_wait(ee->engine.x.sync_counter,
2890                                                 ee->engine.x.sync_val);
2891                }
2892           }
2893      }
2894 }
2895
2896 static void
2897 _ecore_evas_x_flush_post(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__)
2898 {
2899    Ecore_Evas *ee = data;
2900
2901    if (ee->no_comp_sync) return;
2902    if (!_ecore_evas_app_comp_sync) return;
2903    if (ee->engine.x.sync_counter)
2904      {
2905         if (ee->engine.x.sync_began)
2906           {
2907              if (!ee->engine.x.sync_cancel)
2908                {
2909                   ecore_x_e_comp_sync_draw_done_send(ee->engine.x.win_root, 
2910                                                      ee->prop.window);
2911                }
2912           }
2913      }
2914 }
2915 #endif
2916
2917 /**
2918  * To be documented.
2919  *
2920  * FIXME: To be fixed.
2921  */
2922 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
2923 EAPI Ecore_Evas *
2924 ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent,
2925                             int x, int y, int w, int h)
2926 {
2927    Evas_Engine_Info_Software_X11 *einfo;
2928    Ecore_Evas *ee;
2929    int argb = 0;
2930    int rmethod;
2931    static int redraw_debug = -1;
2932
2933    rmethod = evas_render_method_lookup("software_x11");
2934    if (!rmethod) return NULL;
2935    if (!ecore_x_init(disp_name)) return NULL;
2936    ee = calloc(1, sizeof(Ecore_Evas));
2937    if (!ee) return NULL;
2938
2939    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
2940
2941    _ecore_evas_x_init();
2942
2943    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
2944
2945    ee->driver = "software_x11";
2946    if (disp_name) ee->name = strdup(disp_name);
2947
2948    if (w < 1) w = 1;
2949    if (h < 1) h = 1;
2950    ee->x = x;
2951    ee->y = y;
2952    ee->w = w;
2953    ee->h = h;
2954    ee->req.x = ee->x;
2955    ee->req.y = ee->y;
2956    ee->req.w = ee->w;
2957    ee->req.h = ee->h;
2958
2959    ee->prop.max.w = 32767;
2960    ee->prop.max.h = 32767;
2961    ee->prop.layer = 4;
2962    ee->prop.request_pos = 0;
2963    ee->prop.sticky = 0;
2964    ee->engine.x.state.sticky = 0;
2965
2966    /* init evas here */
2967    ee->evas = evas_new();
2968    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
2969    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
2970    evas_data_attach_set(ee->evas, ee);
2971    evas_output_method_set(ee->evas, rmethod);
2972    evas_output_size_set(ee->evas, w, h);
2973    evas_output_viewport_set(ee->evas, 0, 0, w, h);
2974
2975    ee->engine.x.win_root = parent;
2976    ee->engine.x.screen_num = 0;
2977    
2978    if (parent != 0)
2979      {
2980         ee->engine.x.screen_num = 1; /* FIXME: get real scren # */
2981        /* FIXME: round trip in ecore_x_window_argb_get */
2982         if (ecore_x_window_argb_get(parent))
2983           {
2984              ee->prop.window = ecore_x_window_argb_new(parent, x, y, w, h);
2985              argb = 1;
2986           }
2987         else
2988           ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
2989      }
2990    else
2991      ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
2992    if (getenv("DESKTOP_STARTUP_ID"))
2993      {
2994         ecore_x_netwm_startup_id_set(ee->prop.window,
2995                                      getenv("DESKTOP_STARTUP_ID"));
2996         /* NB: on linux this may simply empty the env as opposed to completely
2997          * unset it to being empty - unsure as solartis libc crashes looking
2998          * for the '=' char */
2999 //      putenv((char*)"DESKTOP_STARTUP_ID=");
3000      }
3001    einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
3002    if (einfo)
3003      {
3004 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
3005         xcb_screen_iterator_t iter;
3006         xcb_screen_t         *screen;
3007 # else
3008         int screen;
3009 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
3010
3011         /* FIXME: this is inefficient as its a round trip */
3012 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
3013         screen = ecore_x_default_screen_get();
3014         iter = xcb_setup_roots_iterator (xcb_get_setup (ecore_x_connection_get()));
3015         if (iter.rem > 1)
3016           {
3017              xcb_get_geometry_cookie_t cookie;
3018              xcb_get_geometry_reply_t *reply;
3019              Ecore_X_Window           *roots;
3020              int                       num;
3021              uint8_t                   i;
3022
3023              num = 0;
3024              cookie = xcb_get_geometry_unchecked(ecore_x_connection_get(), parent);
3025              roots = ecore_x_window_root_list(&num);
3026              if (roots)
3027                {
3028                   reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
3029
3030                   if (reply)
3031                     {
3032                        for (i = 0; i < num; xcb_screen_next (&iter), i++)
3033                          {
3034                             if (reply->root == roots[i])
3035                               {
3036                                  screen = iter.data;
3037                                  break;
3038                               }
3039                          }
3040                        free(reply);
3041                     }
3042                   free(roots);
3043                }
3044              else
3045                {
3046                   reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
3047                   if (reply) free(reply);
3048                }
3049           }
3050 # else
3051         screen = DefaultScreen(ecore_x_display_get());
3052         if (ScreenCount(ecore_x_display_get()) > 1)
3053           {
3054              Ecore_X_Window *roots;
3055              int num, i;
3056
3057              num = 0;
3058              roots = ecore_x_window_root_list(&num);
3059              if (roots)
3060                {
3061                   XWindowAttributes at;
3062
3063                   if (XGetWindowAttributes(ecore_x_display_get(),
3064                                            parent, &at))
3065                     {
3066                        for (i = 0; i < num; i++)
3067                          {
3068                             if (at.root == roots[i])
3069                               {
3070                                  screen = i;
3071                                  break;
3072                               }
3073                          }
3074                     }
3075                   free(roots);
3076                }
3077           }
3078 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
3079
3080         if (redraw_debug < 0)
3081           {
3082              if (getenv("REDRAW_DEBUG"))
3083                redraw_debug = atoi(getenv("REDRAW_DEBUG"));
3084              else
3085                redraw_debug = 0;
3086           }
3087 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
3088         einfo->info.backend = EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB;
3089         einfo->info.connection = ecore_x_connection_get();
3090         einfo->info.screen = screen;
3091 # else
3092         einfo->info.backend = EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB;
3093         einfo->info.connection = ecore_x_display_get();
3094         einfo->info.screen = NULL;
3095 #ifdef EVAS_FRAME_QUEUING
3096         {
3097            char    *render_mode;
3098            render_mode = getenv("EVAS_RENDER_MODE");
3099            if (render_mode && !strcmp(render_mode, "non-blocking"))
3100              {
3101                 einfo->render_mode = EVAS_RENDER_MODE_NONBLOCKING;
3102              }
3103         }
3104 #endif
3105
3106 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
3107         einfo->info.drawable = ee->prop.window;
3108         if (argb)
3109           {
3110         /* FIXME: round trip */
3111 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
3112              xcb_get_geometry_cookie_t          cookie_geom;
3113              xcb_get_window_attributes_cookie_t cookie_attr;
3114              xcb_get_geometry_reply_t          *reply_geom;
3115              xcb_get_window_attributes_reply_t *reply_attr;
3116
3117              cookie_geom = xcb_get_geometry_unchecked(ecore_x_connection_get(), ee->prop.window);
3118              cookie_attr = xcb_get_window_attributes_unchecked(ecore_x_connection_get(), ee->prop.window);
3119
3120              reply_geom = xcb_get_geometry_reply(ecore_x_connection_get(), cookie_geom, NULL);
3121              reply_attr = xcb_get_window_attributes_reply(ecore_x_connection_get(), cookie_attr, NULL);
3122              if (reply_attr && reply_geom)
3123                {
3124                   einfo->info.visual   = xcb_visualtype_get(ecore_x_default_screen_get(), reply_attr->visual);
3125                   einfo->info.colormap = reply_attr->colormap;
3126                   einfo->info.depth    = reply_geom->depth;
3127                   einfo->info.destination_alpha = 1;
3128                   free(reply_geom);
3129                   free(reply_attr);
3130                }
3131 # else
3132              XWindowAttributes at;
3133
3134              if (XGetWindowAttributes(ecore_x_display_get(), ee->prop.window,
3135                                       &at))
3136                {
3137                   einfo->info.visual   = at.visual;
3138                   einfo->info.colormap = at.colormap;
3139                   einfo->info.depth    = at.depth;
3140                   einfo->info.destination_alpha = 1;
3141                }
3142 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
3143           }
3144         else
3145           {
3146 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
3147              xcb_screen_t *screen;
3148
3149              screen = ecore_x_default_screen_get();
3150              einfo->info.visual   = xcb_visualtype_get(screen, screen->root_visual);
3151              einfo->info.colormap = screen->default_colormap;
3152              einfo->info.depth    = screen->root_depth;
3153 #else
3154              einfo->info.visual   = DefaultVisual(ecore_x_display_get(), screen);
3155              einfo->info.colormap = DefaultColormap(ecore_x_display_get(), screen);
3156              einfo->info.depth    = DefaultDepth(ecore_x_display_get(), screen);
3157 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
3158              einfo->info.destination_alpha = 0;
3159           }
3160         einfo->info.rotation = 0;
3161         einfo->info.debug    = redraw_debug;
3162         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
3163           {
3164              WRN("evas_engine_info_set() init engine '%s' failed.", ee->driver);
3165              ecore_evas_free(ee);
3166              return NULL;
3167           }
3168      }
3169    ecore_x_icccm_hints_set(ee->prop.window,
3170                            1 /* accepts_focus */,
3171                            ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
3172                            0 /* icon_pixmap */,
3173                            0 /* icon_mask */,
3174                            0 /* icon_window */,
3175                            0 /* window_group */,
3176                            0 /* is_urgent */);
3177
3178    ee->engine.func->fn_render = _ecore_evas_x_render;
3179    _ecore_evas_register(ee);
3180    ecore_x_input_multi_select(ee->prop.window);
3181    ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
3182    return ee;
3183 }
3184 #else
3185 EAPI Ecore_Evas *
3186 ecore_evas_software_x11_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
3187                             int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
3188 {
3189    return NULL;
3190 }
3191 #endif
3192
3193 /**
3194  * To be documented.
3195  *
3196  * FIXME: To be fixed.
3197  */
3198 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
3199 EAPI Ecore_X_Window
3200 ecore_evas_software_x11_window_get(const Ecore_Evas *ee)
3201 {
3202    return (Ecore_X_Window) ecore_evas_window_get(ee);
3203 }
3204 #else
3205 EAPI Ecore_X_Window
3206 ecore_evas_software_x11_window_get(const Ecore_Evas *ee __UNUSED__)
3207 {
3208    return 0;
3209 }
3210 #endif
3211
3212 /**
3213  * To be documented.
3214  *
3215  * FIXME: To be fixed.
3216  */
3217 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
3218 EAPI void
3219 ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee, int on)
3220 {
3221    ee->engine.x.direct_resize = on;
3222    if (ee->prop.avoid_damage)
3223      {
3224         if (ee->engine.x.direct_resize)
3225           {
3226 /* turn this off for now
3227              ee->engine.x.using_bg_pixmap = 1;
3228              ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
3229  */
3230           }
3231         else
3232           {
3233 /* turn this off too- bg pixmap is controlled by avoid damage directly
3234              ee->engine.x.using_bg_pixmap = 0;
3235              ecore_x_window_pixmap_set(ee->prop.window, 0);
3236              ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
3237  */
3238           }
3239      }
3240 }
3241 #else
3242 EAPI void
3243 ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee __UNUSED__, int on __UNUSED__)
3244 {
3245 }
3246 #endif
3247
3248 /**
3249  * To be documented.
3250  *
3251  * FIXME: To be fixed.
3252  */
3253 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
3254 EAPI int
3255 ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee)
3256 {
3257    return ee->engine.x.direct_resize;
3258 }
3259 #else
3260 EAPI int
3261 ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
3262 {
3263    return 0;
3264 }
3265 #endif
3266
3267 /**
3268  * To be documented.
3269  *
3270  * FIXME: To be fixed.
3271  */
3272 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
3273 EAPI void
3274 ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
3275 {
3276    Ecore_X_Window *winp;
3277
3278    winp = malloc(sizeof(Ecore_X_Window));
3279    if (winp)
3280      {
3281         *winp = win;
3282         ee->engine.x.win_extra = eina_list_append(ee->engine.x.win_extra, winp);
3283         ecore_x_input_multi_select(win);
3284         ecore_event_window_register(win, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
3285      }
3286 }
3287 #else
3288 EAPI void
3289 ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
3290 {
3291 }
3292 #endif
3293
3294 /**
3295  * To be documented.
3296  *
3297  * FIXME: To be fixed.
3298  */
3299 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
3300 EAPI Ecore_Evas *
3301 ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent,
3302                       int x, int y, int w, int h)
3303 {
3304    return ecore_evas_gl_x11_options_new(disp_name, parent, x, y, w, h, NULL);
3305 }
3306 EAPI Ecore_Evas *
3307 ecore_evas_gl_x11_options_new(const char *disp_name, Ecore_X_Window parent,
3308                               int x, int y, int w, int h, const int *opt)
3309 {
3310 # ifdef HAVE_ECORE_X_XCB
3311    Ecore_Evas *ee = NULL;
3312 # else
3313    Ecore_Evas *ee;
3314    int rmethod;
3315
3316    rmethod = evas_render_method_lookup("gl_x11");
3317    if (!rmethod) return NULL;
3318    if (!ecore_x_init(disp_name)) return NULL;
3319    ee = calloc(1, sizeof(Ecore_Evas));
3320    if (!ee) return NULL;
3321
3322    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
3323
3324    _ecore_evas_x_init();
3325
3326    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
3327
3328    ee->driver = "opengl_x11";
3329    if (disp_name) ee->name = strdup(disp_name);
3330
3331    if (w < 1) w = 1;
3332    if (h < 1) h = 1;
3333    ee->x = x;
3334    ee->y = y;
3335    ee->w = w;
3336    ee->h = h;
3337    ee->req.x = ee->x;
3338    ee->req.y = ee->y;
3339    ee->req.w = ee->w;
3340    ee->req.h = ee->h;
3341
3342    ee->prop.max.w = 32767;
3343    ee->prop.max.h = 32767;
3344    ee->prop.layer = 4;
3345    ee->prop.request_pos = 0;
3346    ee->prop.sticky = 0;
3347    ee->engine.x.state.sticky = 0;
3348
3349    /* init evas here */
3350    ee->evas = evas_new();
3351    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
3352    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
3353    evas_data_attach_set(ee->evas, ee);
3354    evas_output_method_set(ee->evas, rmethod);
3355    evas_output_size_set(ee->evas, w, h);
3356    evas_output_viewport_set(ee->evas, 0, 0, w, h);
3357
3358    if (parent == 0) parent = DefaultRootWindow(ecore_x_display_get());
3359    ee->engine.x.win_root = parent;
3360
3361    if (ee->engine.x.win_root != 0)
3362      {
3363         ee->engine.x.screen_num = 1; /* FIXME: get real scren # */
3364        /* FIXME: round trip in ecore_x_window_argb_get */
3365         if (ecore_x_window_argb_get(ee->engine.x.win_root))
3366           {
3367              ee->prop.window = _ecore_evas_x_gl_window_new
3368                (ee, ee->engine.x.win_root, x, y, w, h, 0, 1, opt);
3369           }
3370         else
3371           ee->prop.window = _ecore_evas_x_gl_window_new
3372           (ee, ee->engine.x.win_root, x, y, w, h, 0, 0, opt);
3373      }
3374    else
3375      ee->prop.window = _ecore_evas_x_gl_window_new
3376      (ee, ee->engine.x.win_root, x, y, w, h, 0, 0, opt);
3377    if (!ee->prop.window)
3378      {
3379         ecore_evas_free(ee);
3380         return NULL;
3381      }
3382    if (getenv("DESKTOP_STARTUP_ID"))
3383      {
3384         ecore_x_netwm_startup_id_set(ee->prop.window,
3385                                      getenv("DESKTOP_STARTUP_ID"));
3386         /* NB: on linux this may simply empty the env as opposed to completely
3387          * unset it to being empty - unsure as solartis libc crashes looking
3388          * for the '=' char */
3389 //      putenv((char*)"DESKTOP_STARTUP_ID=");
3390      }
3391
3392    ecore_x_icccm_hints_set(ee->prop.window,
3393                            1 /* accepts_focus */,
3394                            ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
3395                            0 /* icon_pixmap */,
3396                            0 /* icon_mask */,
3397                            0 /* icon_window */,
3398                            0 /* window_group */,
3399                            0 /* is_urgent */);
3400    
3401    ee->engine.func->fn_render = _ecore_evas_x_render;
3402    _ecore_evas_register(ee);
3403    ecore_x_input_multi_select(ee->prop.window);
3404    ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
3405 # endif /* HAVE_ECORE_X_XCB */
3406
3407    return ee;
3408 }
3409 #else
3410 EAPI Ecore_Evas *
3411 ecore_evas_gl_x11_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
3412                       int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
3413 {
3414    return NULL;
3415 }
3416 EAPI Ecore_Evas *
3417 ecore_evas_gl_x11_options_new(const char *disp_name, Ecore_X_Window parent,
3418                               int x, int y, int w, int h, const int *opt)
3419 {
3420    return NULL;
3421 }
3422 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3423
3424 /**
3425  * To be documented.
3426  *
3427  * FIXME: To be fixed.
3428  */
3429 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
3430 EAPI Ecore_X_Window
3431 ecore_evas_gl_x11_window_get(const Ecore_Evas *ee)
3432 {
3433    return (Ecore_X_Window) ecore_evas_window_get(ee);
3434 }
3435 #else
3436 EAPI Ecore_X_Window
3437 ecore_evas_gl_x11_window_get(const Ecore_Evas *ee __UNUSED__)
3438 {
3439    return 0;
3440 }
3441 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3442
3443 /**
3444  * To be documented.
3445  *
3446  * FIXME: To be fixed.
3447  */
3448 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
3449 EAPI void
3450 ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee, int on)
3451 {
3452    ee->engine.x.direct_resize = on;
3453 }
3454 #else
3455 EAPI void
3456 ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee __UNUSED__, int on __UNUSED__)
3457 {
3458 }
3459 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3460
3461 /**
3462  * To be documented.
3463  *
3464  * FIXME: To be fixed.
3465  */
3466 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
3467 EAPI int
3468 ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee)
3469 {
3470    return ee->engine.x.direct_resize;
3471 }
3472 #else
3473 EAPI int
3474 ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
3475 {
3476    return 0;
3477 }
3478 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3479
3480 /**
3481  * To be documented.
3482  *
3483  * FIXME: To be fixed.
3484  */
3485 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
3486 EAPI void
3487 ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
3488 {
3489    ecore_evas_software_x11_extra_event_window_add(ee, win);
3490 }
3491 #else
3492 EAPI void
3493 ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
3494 {
3495 }
3496 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3497
3498 /**
3499  * To be documented.
3500  *
3501  * FIXME: To be fixed.
3502  */
3503 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
3504 EAPI void
3505 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))
3506 {
3507    Evas_Engine_Info_GL_X11 *einfo;
3508    
3509    if (!(!strcmp(ee->driver, "opengl_x11"))) return;
3510  
3511    einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
3512    if (einfo)
3513      {
3514         einfo->callback.pre_swap = pre_cb;
3515         einfo->callback.pre_swap = post_cb;
3516         einfo->callback.data = data;
3517         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
3518           {
3519              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
3520           }
3521      }
3522 }
3523 #else
3524 EAPI void
3525 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))
3526 {
3527    return;
3528 }
3529 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3530
3531 /**
3532  * To be documented.
3533  *
3534  * FIXME: To be fixed.
3535  */
3536 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
3537 EAPI Ecore_Evas *
3538 ecore_evas_xrender_x11_new(const char *disp_name, Ecore_X_Window parent,
3539                       int x, int y, int w, int h)
3540 {
3541    Evas_Engine_Info_XRender_X11 *einfo;
3542    Ecore_Evas *ee;
3543    int rmethod;
3544
3545    rmethod = evas_render_method_lookup("xrender_x11");
3546    if (!rmethod) return NULL;
3547    if (!ecore_x_init(disp_name)) return NULL;
3548    ee = calloc(1, sizeof(Ecore_Evas));
3549    if (!ee) return NULL;
3550
3551    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
3552
3553    _ecore_evas_x_init();
3554
3555    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
3556
3557    ee->driver = "xrender_x11";
3558    if (disp_name) ee->name = strdup(disp_name);
3559
3560    if (w < 1) w = 1;
3561    if (h < 1) h = 1;
3562    ee->x = x;
3563    ee->y = y;
3564    ee->w = w;
3565    ee->h = h;
3566    ee->req.x = ee->x;
3567    ee->req.y = ee->y;
3568    ee->req.w = ee->w;
3569    ee->req.h = ee->h;
3570
3571    ee->prop.max.w = 32767;
3572    ee->prop.max.h = 32767;
3573    ee->prop.layer = 4;
3574    ee->prop.request_pos = 0;
3575    ee->prop.sticky = 0;
3576    ee->engine.x.state.sticky = 0;
3577
3578    /* init evas here */
3579    ee->evas = evas_new();
3580    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
3581    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
3582    evas_data_attach_set(ee->evas, ee);
3583    evas_output_method_set(ee->evas, rmethod);
3584    evas_output_size_set(ee->evas, w, h);
3585    evas_output_viewport_set(ee->evas, 0, 0, w, h);
3586
3587    ee->engine.x.win_root = parent;
3588    ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
3589    if (getenv("DESKTOP_STARTUP_ID"))
3590      {
3591         ecore_x_netwm_startup_id_set(ee->prop.window,
3592                                      getenv("DESKTOP_STARTUP_ID"));
3593         /* NB: on linux this may simply empty the env as opposed to completely
3594          * unset it to being empty - unsure as solartis libc crashes looking
3595          * for the '=' char */
3596 //      putenv((char*)"DESKTOP_STARTUP_ID=");
3597      }
3598    einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
3599    if (einfo)
3600      {
3601 # ifdef BUILD_ECORE_EVAS_XRENDER_XCB
3602         xcb_screen_iterator_t iter;
3603         xcb_screen_t         *screen;
3604
3605         /* FIXME: this is inefficient as its a round trip */
3606         screen = ecore_x_default_screen_get();
3607         iter = xcb_setup_roots_iterator (xcb_get_setup (ecore_x_connection_get()));
3608         if (iter.rem > 1)
3609           {
3610              xcb_get_geometry_cookie_t cookie;
3611              xcb_get_geometry_reply_t *reply;
3612              Ecore_X_Window           *roots;
3613              int                       num;
3614              uint8_t                   i;
3615
3616              num = 0;
3617              cookie = xcb_get_geometry_unchecked(ecore_x_connection_get(), parent);
3618              roots = ecore_x_window_root_list(&num);
3619              if (roots)
3620                {
3621                   reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
3622
3623                   if (reply)
3624                     {
3625                        for (i = 0; i < num; xcb_screen_next (&iter), i++)
3626                          {
3627                             if (reply->root == roots[i])
3628                               {
3629                                  screen = iter.data;
3630                                  break;
3631                               }
3632                          }
3633                        free(reply);
3634                     }
3635                   free(roots);
3636                }
3637              else
3638                {
3639                   reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
3640                   if (reply) free(reply);
3641                }
3642           }
3643         einfo->info.backend = EVAS_ENGINE_INFO_XRENDER_BACKEND_XCB;
3644         einfo->info.connection = ecore_x_connection_get();
3645         einfo->info.screen = screen;
3646         einfo->info.visual = screen->root_visual;
3647 # elif BUILD_ECORE_EVAS_XRENDER_X11
3648         int screen;
3649
3650         /* FIXME: this is inefficient as its a round trip */
3651         screen = DefaultScreen(ecore_x_display_get());
3652         if (ScreenCount(ecore_x_display_get()) > 1)
3653           {
3654              Ecore_X_Window *roots;
3655              int num, i;
3656
3657              num = 0;
3658              roots = ecore_x_window_root_list(&num);
3659              if (roots)
3660                {
3661                   XWindowAttributes at;
3662
3663                   if (XGetWindowAttributes(ecore_x_display_get(),
3664                                            parent, &at))
3665                     {
3666                        for (i = 0; i < num; i++)
3667                          {
3668                             if (at.root == roots[i])
3669                               {
3670                                  screen = i;
3671                                  break;
3672                               }
3673                          }
3674                     }
3675                   free(roots);
3676                }
3677           }
3678         einfo->info.backend = EVAS_ENGINE_INFO_XRENDER_BACKEND_XLIB;
3679         einfo->info.connection = ecore_x_display_get();
3680         einfo->info.screen = NULL;
3681         einfo->info.visual = DefaultVisual(ecore_x_display_get(), screen);
3682 # endif /* BUILD_ECORE_EVAS_XRENDER_(XCB|X11) */
3683         einfo->info.drawable = ee->prop.window;
3684         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
3685           {
3686              WRN("evas_engine_info_set() init engine '%s' failed.", ee->driver);
3687              ecore_evas_free(ee);
3688              return NULL;
3689           }
3690      }
3691
3692    ecore_x_icccm_hints_set(ee->prop.window,
3693                            1 /* accepts_focus */,
3694                            ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
3695                            0 /* icon_pixmap */,
3696                            0 /* icon_mask */,
3697                            0 /* icon_window */,
3698                            0 /* window_group */,
3699                            0 /* is_urgent */);
3700    
3701    ee->engine.func->fn_render = _ecore_evas_x_render;
3702    _ecore_evas_register(ee);
3703    ecore_x_input_multi_select(ee->prop.window);
3704    ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
3705    return ee;
3706 }
3707 #else
3708 EAPI Ecore_Evas *
3709 ecore_evas_xrender_x11_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
3710                            int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
3711 {
3712    return NULL;
3713 }
3714 #endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
3715
3716 /**
3717  * To be documented.
3718  *
3719  * FIXME: To be fixed.
3720  */
3721 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
3722 EAPI Ecore_X_Window
3723 ecore_evas_xrender_x11_window_get(const Ecore_Evas *ee)
3724 {
3725    return (Ecore_X_Window) ecore_evas_window_get(ee);
3726 }
3727 #else
3728 EAPI Ecore_X_Window
3729 ecore_evas_xrender_x11_window_get(const Ecore_Evas *ee __UNUSED__)
3730 {
3731    return 0;
3732 }
3733 #endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
3734
3735 /**
3736  * To be documented.
3737  *
3738  * FIXME: To be fixed.
3739  */
3740 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
3741 EAPI void
3742 ecore_evas_xrender_x11_direct_resize_set(Ecore_Evas *ee, int on)
3743 {
3744    ee->engine.x.direct_resize = on;
3745 }
3746 #else
3747 EAPI void
3748 ecore_evas_xrender_x11_direct_resize_set(Ecore_Evas *ee __UNUSED__, int on __UNUSED__)
3749 {
3750 }
3751 #endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
3752
3753 /**
3754  * To be documented.
3755  *
3756  * FIXME: To be fixed.
3757  */
3758 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
3759 EAPI int
3760 ecore_evas_xrender_x11_direct_resize_get(const Ecore_Evas *ee)
3761 {
3762    return ee->engine.x.direct_resize;
3763 }
3764 #else
3765 EAPI int
3766 ecore_evas_xrender_x11_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
3767 {
3768    return 0;
3769 }
3770 #endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
3771
3772 /**
3773  * To be documented.
3774  *
3775  * FIXME: To be fixed.
3776  */
3777 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
3778 EAPI void
3779 ecore_evas_xrender_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
3780 {
3781    ecore_evas_software_x11_extra_event_window_add(ee, win);
3782 }
3783 #else
3784 EAPI void
3785 ecore_evas_xrender_x11_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
3786 {
3787 }
3788 #endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
3789
3790 /**
3791  * To be documented.
3792  *
3793  * FIXME: To be fixed.
3794  */
3795 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
3796 EAPI Ecore_Evas *
3797 ecore_evas_software_x11_16_new(const char *disp_name, Ecore_X_Window parent,
3798                                int x, int y, int w, int h)
3799 {
3800    Evas_Engine_Info_Software_16_X11 *einfo;
3801    Ecore_Evas *ee;
3802    int rmethod;
3803    static int redraw_debug = -1;
3804
3805    rmethod = evas_render_method_lookup("software_16_x11");
3806    if (!rmethod) return NULL;
3807    if (!ecore_x_init(disp_name)) return NULL;
3808    ee = calloc(1, sizeof(Ecore_Evas));
3809    if (!ee) return NULL;
3810
3811    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
3812
3813    _ecore_evas_x_init();
3814
3815    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
3816
3817    ee->driver = "software_16_x11";
3818    if (disp_name) ee->name = strdup(disp_name);
3819
3820    if (w < 1) w = 1;
3821    if (h < 1) h = 1;
3822    ee->x = x;
3823    ee->y = y;
3824    ee->w = w;
3825    ee->h = h;
3826    ee->req.x = ee->x;
3827    ee->req.y = ee->y;
3828    ee->req.w = ee->w;
3829    ee->req.h = ee->h;
3830
3831    ee->prop.max.w = 32767;
3832    ee->prop.max.h = 32767;
3833    ee->prop.layer = 4;
3834    ee->prop.request_pos = 0;
3835    ee->prop.sticky = 0;
3836    ee->engine.x.state.sticky = 0;
3837
3838    /* init evas here */
3839    ee->evas = evas_new();
3840    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
3841    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
3842    evas_data_attach_set(ee->evas, ee);
3843    evas_output_method_set(ee->evas, rmethod);
3844    evas_output_size_set(ee->evas, w, h);
3845    evas_output_viewport_set(ee->evas, 0, 0, w, h);
3846
3847    ee->engine.x.win_root = parent;
3848    if (parent != 0)
3849      {
3850        /* FIXME: round trip in ecore_x_window_argb_get */
3851         if (ecore_x_window_argb_get(parent))
3852           {
3853              ee->prop.window = ecore_x_window_argb_new(parent, x, y, w, h);
3854           }
3855         else
3856           ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
3857      }
3858    else
3859      ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
3860    if (getenv("DESKTOP_STARTUP_ID"))
3861      {
3862         ecore_x_netwm_startup_id_set(ee->prop.window,
3863                                      getenv("DESKTOP_STARTUP_ID"));
3864         /* NB: on linux this may simply empty the env as opposed to completely
3865          * unset it to being empty - unsure as solartis libc crashes looking
3866          * for the '=' char */
3867 //      putenv((char*)"DESKTOP_STARTUP_ID=");
3868      }
3869    einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
3870
3871    if (einfo)
3872      {
3873         if (ScreenCount(ecore_x_display_get()) > 1)
3874           {
3875              Ecore_X_Window *roots;
3876              int num, i;
3877
3878              num = 0;
3879              roots = ecore_x_window_root_list(&num);
3880              if (roots)
3881                {
3882                   XWindowAttributes at;
3883
3884                   if (XGetWindowAttributes(ecore_x_display_get(),
3885                                            parent, &at))
3886                     {
3887                        for (i = 0; i < num; i++)
3888                          {
3889                             if (at.root == roots[i])
3890                               break;
3891                          }
3892                     }
3893                   free(roots);
3894                }
3895           }
3896
3897         if (redraw_debug < 0)
3898           {
3899              if (getenv("REDRAW_DEBUG"))
3900                redraw_debug = atoi(getenv("REDRAW_DEBUG"));
3901              else
3902                redraw_debug = 0;
3903           }
3904         einfo->info.display  = ecore_x_display_get();
3905         einfo->info.drawable = ee->prop.window;
3906
3907         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
3908           {
3909              WRN("evas_engine_info_set() init engine '%s' failed.", ee->driver);
3910              ecore_evas_free(ee);
3911              return NULL;
3912           }
3913      }
3914
3915    ecore_x_icccm_hints_set(ee->prop.window,
3916                            1 /* accepts_focus */,
3917                            ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
3918                            0 /* icon_pixmap */,
3919                            0 /* icon_mask */,
3920                            0 /* icon_window */,
3921                            0 /* window_group */,
3922                            0 /* is_urgent */);
3923    
3924    ee->engine.func->fn_render = _ecore_evas_x_render;
3925    _ecore_evas_register(ee);
3926    ecore_x_input_multi_select(ee->prop.window);
3927    ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
3928    return ee;
3929 }
3930 #else
3931 EAPI Ecore_Evas *
3932 ecore_evas_software_x11_16_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
3933                                int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
3934 {
3935    return NULL;
3936 }
3937 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
3938
3939 /**
3940  * To be documented.
3941  *
3942  * FIXME: To be fixed.
3943  */
3944 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
3945 EAPI Ecore_X_Window
3946 ecore_evas_software_x11_16_window_get(const Ecore_Evas *ee)
3947 {
3948    return (Ecore_X_Window) ecore_evas_window_get(ee);
3949 }
3950 #else
3951 EAPI Ecore_X_Window
3952 ecore_evas_software_x11_16_window_get(const Ecore_Evas *ee __UNUSED__)
3953 {
3954    return 0;
3955 }
3956 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
3957
3958 /**
3959  * To be documented.
3960  *
3961  * FIXME: To be fixed.
3962  */
3963 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
3964 EAPI void
3965 ecore_evas_software_x11_16_direct_resize_set(Ecore_Evas *ee, int on)
3966 {
3967    ee->engine.x.direct_resize = on;
3968    if (ee->prop.avoid_damage)
3969      {
3970         if (ee->engine.x.direct_resize)
3971           {
3972 /* turn this off for now
3973              ee->engine.x.using_bg_pixmap = 1;
3974              ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
3975  */
3976           }
3977         else
3978           {
3979 /* turn this off too- bg pixmap is controlled by avoid damage directly
3980              ee->engine.x.using_bg_pixmap = 0;
3981              ecore_x_window_pixmap_set(ee->prop.window, 0);
3982              ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
3983  */
3984           }
3985      }
3986 }
3987 #else
3988 EAPI void
3989 ecore_evas_software_x11_16_direct_resize_set(Ecore_Evas *ee __UNUSED__, int on __UNUSED__)
3990 {
3991 }
3992 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
3993
3994 /**
3995  * To be documented.
3996  *
3997  * FIXME: To be fixed.
3998  */
3999 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
4000 EAPI int
4001 ecore_evas_software_x11_16_direct_resize_get(const Ecore_Evas *ee)
4002 {
4003    return ee->engine.x.direct_resize;
4004 }
4005 #else
4006 EAPI int
4007 ecore_evas_software_x11_16_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
4008 {
4009    return 0;
4010 }
4011 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
4012
4013 /**
4014  * To be documented.
4015  *
4016  * FIXME: To be fixed.
4017  */
4018 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
4019 EAPI void
4020 ecore_evas_software_x11_16_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
4021 {
4022    Ecore_X_Window *winp;
4023
4024    winp = malloc(sizeof(Ecore_X_Window));
4025    if (winp)
4026      {
4027         *winp = win;
4028         ee->engine.x.win_extra = eina_list_append(ee->engine.x.win_extra, winp);
4029         ecore_x_input_multi_select(win);
4030         ecore_event_window_register(win, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
4031      }
4032 }
4033 #else
4034 EAPI void
4035 ecore_evas_software_x11_16_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
4036 {
4037 }
4038 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
4039
4040
4041 /**
4042  * To be documented.
4043  *
4044  * FIXME: To be fixed.
4045  */
4046 EAPI Ecore_Evas *
4047 ecore_evas_software_x11_8_new(const char *disp_name, Ecore_X_Window parent,
4048                               int x, int y, int w, int h)
4049 {
4050 #if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
4051    Evas_Engine_Info_Software_8_X11 *einfo;
4052    Ecore_Evas *ee;
4053    int argb = 0;
4054    int rmethod;
4055    static int redraw_debug = -1;
4056
4057    rmethod = evas_render_method_lookup("software_8_x11");
4058    if (!rmethod) return NULL;
4059    if (!ecore_x_init(disp_name)) return NULL;
4060    ee = calloc(1, sizeof(Ecore_Evas));
4061    if (!ee) return NULL;
4062
4063    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
4064
4065    _ecore_evas_x_init();
4066
4067    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
4068
4069    ee->driver = "software_8_x11";
4070    if (disp_name) ee->name = strdup(disp_name);
4071
4072    if (w < 1) w = 1;
4073    if (h < 1) h = 1;
4074    ee->x = x;
4075    ee->y = y;
4076    ee->w = w;
4077    ee->h = h;
4078    ee->req.x = ee->x;
4079    ee->req.y = ee->y;
4080    ee->req.w = ee->w;
4081    ee->req.h = ee->h;
4082
4083    ee->prop.max.w = 32767;
4084    ee->prop.max.h = 32767;
4085    ee->prop.layer = 4;
4086    ee->prop.request_pos = 0;
4087    ee->prop.sticky = 0;
4088    ee->engine.x.state.sticky = 0;
4089
4090    /* init evas here */
4091    ee->evas = evas_new();
4092    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
4093    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
4094    evas_data_attach_set(ee->evas, ee);
4095    evas_output_method_set(ee->evas, rmethod);
4096    evas_output_size_set(ee->evas, w, h);
4097    evas_output_viewport_set(ee->evas, 0, 0, w, h);
4098
4099    ee->engine.x.win_root = parent;
4100    //   if (parent != 0)
4101    //     {
4102    //       /* FIXME: round trip in ecore_x_window_argb_get */
4103    //   if (ecore_x_window_argb_get(parent))
4104    //     {
4105    //        ee->engine.x.win = ecore_x_window_argb_new(parent, x, y, w, h);
4106    //        argb = 1;
4107    //     }
4108    //   else
4109    //     ee->engine.x.win = ecore_x_window_new(parent, x, y, w, h);
4110    //     }
4111    //   else
4112    ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
4113    if (getenv("DESKTOP_STARTUP_ID"))
4114      {
4115         ecore_x_netwm_startup_id_set(ee->prop.window,
4116               getenv("DESKTOP_STARTUP_ID"));
4117         /* NB: on linux this may simply empty the env as opposed to completely
4118          * unset it to being empty - unsure as solartis libc crashes looking
4119          * for the '=' char */
4120         //      putenv((char*)"DESKTOP_STARTUP_ID=");
4121      }
4122    einfo = (Evas_Engine_Info_Software_8_X11 *)evas_engine_info_get(ee->evas);
4123    if (einfo)
4124      {
4125         xcb_screen_iterator_t iter;
4126         xcb_screen_t         *screen;
4127
4128         /* FIXME: this is inefficient as its a round trip */
4129         //einfo->info.backend = 1;
4130         screen = ecore_x_default_screen_get();
4131         iter = xcb_setup_roots_iterator (xcb_get_setup (ecore_x_connection_get()));
4132         if (iter.rem > 1)
4133           {
4134              xcb_get_geometry_cookie_t cookie;
4135              xcb_get_geometry_reply_t *reply;
4136              Ecore_X_Window           *roots;
4137              int                       num;
4138              uint8_t                   i;
4139
4140              num = 0;
4141              cookie = xcb_get_geometry_unchecked(ecore_x_connection_get(), parent);
4142              roots = ecore_x_window_root_list(&num);
4143              if (roots)
4144                {
4145                   reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
4146
4147                   if (reply)
4148                     {
4149                        for (i = 0; i < num; xcb_screen_next (&iter), i++)
4150                          {
4151                             if (reply->root == roots[i])
4152                               {
4153                                  screen = iter.data;
4154                                  break;
4155                               }
4156                          }
4157                        free(reply);
4158                     }
4159                   free(roots);
4160                }
4161              else
4162                {
4163                   reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
4164                   if (reply) free(reply);
4165                }
4166           }
4167
4168         if (redraw_debug < 0)
4169           {
4170              if (getenv("REDRAW_DEBUG"))
4171                redraw_debug = atoi(getenv("REDRAW_DEBUG"));
4172              else
4173                redraw_debug = 0;
4174           }
4175         einfo->info.connection = ecore_x_connection_get();
4176         einfo->info.screen = screen;
4177         einfo->info.drawable = ee->prop.window;
4178         if (argb)
4179           {
4180              /* FIXME: round trip */
4181              xcb_get_geometry_cookie_t          cookie_geom;
4182              xcb_get_window_attributes_cookie_t cookie_attr;
4183              xcb_get_geometry_reply_t          *reply_geom;
4184              xcb_get_window_attributes_reply_t *reply_attr;
4185
4186              cookie_geom = xcb_get_geometry_unchecked(ecore_x_connection_get(), ee->prop.window);
4187              cookie_attr = xcb_get_window_attributes_unchecked(ecore_x_connection_get(), ee->prop.window);
4188
4189              reply_geom = xcb_get_geometry_reply(ecore_x_connection_get(), cookie_geom, NULL);
4190              reply_attr = xcb_get_window_attributes_reply(ecore_x_connection_get(), cookie_attr, NULL);
4191              if (reply_attr && reply_geom)
4192                {
4193                   einfo->info.visual   = xcb_visualtype_get(ecore_x_default_screen_get(), reply_attr->visual);
4194                   einfo->info.colormap = reply_attr->colormap;
4195                   einfo->info.depth    = reply_geom->depth;
4196                   einfo->info.destination_alpha = 1;
4197                   free(reply_geom);
4198                   free(reply_attr);
4199                }
4200           }
4201         else
4202           {
4203              xcb_screen_t *screen;
4204
4205              screen = ecore_x_default_screen_get();
4206              einfo->info.visual   = xcb_visualtype_get(screen, screen->root_visual);
4207              einfo->info.colormap = screen->default_colormap;
4208              einfo->info.depth    = screen->root_depth;
4209              einfo->info.destination_alpha = 0;
4210           }
4211         einfo->info.rotation = 0;
4212         einfo->info.debug    = redraw_debug;
4213     if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
4214     {
4215         WRN("evas_engine_info_set() init engine '%s' failed.", ee->driver);
4216         ecore_evas_free(ee);
4217         return NULL;
4218     }
4219      }
4220
4221    ecore_x_icccm_hints_set(ee->prop.window,
4222                            1 /* accepts_focus */,
4223                            ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
4224                            0 /* icon_pixmap */,
4225                            0 /* icon_mask */,
4226                            0 /* icon_window */,
4227                            0 /* window_group */,
4228                            0 /* is_urgent */);
4229
4230    ee->engine.func->fn_render = _ecore_evas_x_render;
4231    _ecore_evas_register(ee);
4232    ecore_x_input_multi_select(ee->prop.window);
4233    ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
4234
4235    return ee;
4236 #else
4237    return NULL;
4238 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_8_X11 */
4239 }
4240
4241 /**
4242  * To be documented.
4243  *
4244  * FIXME: To be fixed.
4245  */
4246 EAPI Ecore_X_Window
4247 ecore_evas_software_x11_8_window_get(const Ecore_Evas *ee)
4248 {
4249 #if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
4250    return (Ecore_X_Window) ecore_evas_window_get(ee);
4251 #else
4252    return 0;
4253 #endif
4254 }
4255
4256 /**
4257  * To be documented.
4258  *
4259  * FIXME: To be fixed.
4260  */
4261 EAPI Ecore_X_Window
4262 ecore_evas_software_x11_8_subwindow_get(const Ecore_Evas *ee)
4263 {
4264 #if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
4265    return (Ecore_X_Window) ecore_evas_window_get(ee);
4266 #else
4267    return 0;
4268 #endif
4269 }
4270
4271 /**
4272  * To be documented.
4273  *
4274  * FIXME: To be fixed.
4275  */
4276 EAPI void
4277 ecore_evas_software_x11_8_direct_resize_set(Ecore_Evas *ee, int on)
4278 {
4279 #if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
4280    ee->engine.x.direct_resize = on;
4281    if (ee->prop.avoid_damage)
4282      {
4283         if (ee->engine.x.direct_resize)
4284           {
4285              /* turn this off for now
4286                 ee->engine.x.using_bg_pixmap = 1;
4287                 ecore_x_window_pixmap_set(ee->engine.x.win, ee->engine.x.pmap);
4288                 */
4289           }
4290         else
4291           {
4292              /* turn this off too- bg pixmap is controlled by avoid damage directly
4293                 ee->engine.x.using_bg_pixmap = 0;
4294                 ecore_x_window_pixmap_set(ee->engine.x.win, 0);
4295                 ecore_x_window_area_expose(ee->engine.x.win, 0, 0, ee->w, ee->h);
4296                 */
4297           }
4298      }
4299 #else
4300    return;
4301 #endif
4302 }
4303
4304 /**
4305  * To be documented.
4306  *
4307  * FIXME: To be fixed.
4308  */
4309 EAPI int
4310 ecore_evas_software_x11_8_direct_resize_get(const Ecore_Evas *ee)
4311 {
4312 #if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
4313    return ee->engine.x.direct_resize;
4314 #else
4315    return 0;
4316 #endif
4317 }
4318
4319 /**
4320  * To be documented.
4321  *
4322  * FIXME: To be fixed.
4323  */
4324 EAPI void
4325 ecore_evas_software_x11_8_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
4326 {
4327 #if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
4328    Ecore_X_Window *winp;
4329
4330    winp = malloc(sizeof(Ecore_X_Window));
4331    if (winp)
4332      {
4333         *winp = win;
4334         ee->engine.x.win_extra = eina_list_append(ee->engine.x.win_extra, winp);
4335         ecore_x_input_multi_select(win);
4336         ecore_event_window_register(win, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
4337      }
4338 #else
4339 #endif
4340 }