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