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