svn update: 60286 (latest:60286)
[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    /* some GL drivers are doing buffer copy in a separate thread.
1081     * we need to check whether GL driver sends SYNC_DRAW_DONE msg afger copying
1082     * that are required in order to exactly render. - added by gl77.lee
1083     */
1084    if (ee->gl_sync_draw_done < 0)
1085      {
1086         if (getenv("ECORE_EVAS_GL_SYNC_DRAW_DONE"))
1087            ee->gl_sync_draw_done = atoi(getenv("ECORE_EVAS_GL_SYNC_DRAW_DONE"));
1088         else
1089            ee->gl_sync_draw_done = 0;
1090      }
1091    if (first_map_bug < 0)
1092      {
1093         if (getenv("ECORE_EVAS_GL_FIRST_MAP_BUG"))
1094            first_map_bug = atoi(getenv("ECORE_EVAS_GL_FIRST_MAP_BUG"));
1095         else
1096            first_map_bug = 0;
1097      }
1098    if ((first_map_bug) &&
1099        (!strcmp(ee->driver, "opengl_x11")))
1100       evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1101    if (ee->visible) return ECORE_CALLBACK_DONE;
1102 //   printf("SHOW EVENT %p\n", ee);
1103    ee->visible = 1;
1104    if (ee->func.fn_show) ee->func.fn_show(ee);
1105    return ECORE_CALLBACK_PASS_ON;
1106 }
1107
1108 static Eina_Bool
1109 _ecore_evas_x_event_window_hide(void *data __UNUSED__, int type __UNUSED__, void *event)
1110 {
1111    Ecore_Evas *ee;
1112    Ecore_X_Event_Window_Hide *e;
1113
1114    e = event;
1115    ee = ecore_event_window_match(e->win);
1116    if (!ee) return ECORE_CALLBACK_PASS_ON; /* pass on event */
1117    if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
1118    if (!ee->visible) return ECORE_CALLBACK_DONE;
1119 //   printf("HIDE EVENT %p\n", ee);
1120    ee->visible = 0;
1121    if (ee->func.fn_hide) ee->func.fn_hide(ee);
1122    return ECORE_CALLBACK_PASS_ON;
1123 }
1124
1125 /* FIXME, should be in idler */
1126 /* FIXME, round trip */
1127 static void
1128 _ecore_evas_x_size_pos_hints_update(Ecore_Evas *ee)
1129 {
1130 # ifdef HAVE_ECORE_X_XCB
1131    ecore_x_icccm_size_pos_hints_get_prefetch(ee->prop.window);
1132    ecore_x_icccm_size_pos_hints_get_fetch();
1133 # endif /* HAVE_ECORE_X_XCB */
1134    ecore_x_icccm_size_pos_hints_set(ee->prop.window,
1135                                     ee->prop.request_pos /*request_pos */,
1136                                     ECORE_X_GRAVITY_NW /* gravity */,
1137                                     ee->prop.min.w /* min_w */,
1138                                     ee->prop.min.h /* min_h */,
1139                                     ee->prop.max.w /* max_w */,
1140                                     ee->prop.max.h /* max_h */,
1141                                     ee->prop.base.w /* base_w */,
1142                                     ee->prop.base.h /* base_h */,
1143                                     ee->prop.step.w /* step_x */,
1144                                     ee->prop.step.h /* step_y */,
1145                                     0 /* min_aspect */,
1146                                     0 /* max_aspect */);
1147 # ifdef HAVE_ECORE_X_XCB
1148    ecore_xcb_reply_free();
1149 # endif /* HAVE_ECORE_X_XCB */
1150 }
1151
1152 /* FIXME, should be in idler */
1153 static void
1154 _ecore_evas_x_state_update(Ecore_Evas *ee)
1155 {
1156    Ecore_X_Window_State state[10];
1157    int num;
1158
1159    num = 0;
1160
1161    /*
1162    if (bd->client.netwm.state.modal)
1163      state[num++] = ECORE_X_WINDOW_STATE_MODAL;
1164    */
1165    if (ee->engine.x.state.sticky)
1166      state[num++] = ECORE_X_WINDOW_STATE_STICKY;
1167    /*
1168    if (bd->client.netwm.state.maximized_v)
1169      state[num++] = ECORE_X_WINDOW_STATE_MAXIMIZED_VERT;
1170    if (bd->client.netwm.state.maximized_h)
1171      state[num++] = ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ;
1172    if (bd->client.netwm.state.shaded)
1173      state[num++] = ECORE_X_WINDOW_STATE_SHADED;
1174    if (bd->client.netwm.state.skip_taskbar)
1175      state[num++] = ECORE_X_WINDOW_STATE_SKIP_TASKBAR;
1176    if (bd->client.netwm.state.skip_pager)
1177      state[num++] = ECORE_X_WINDOW_STATE_SKIP_PAGER;
1178    if (bd->client.netwm.state.hidden)
1179      state[num++] = ECORE_X_WINDOW_STATE_HIDDEN;
1180    */
1181    if (ee->engine.x.state.fullscreen)
1182      state[num++] = ECORE_X_WINDOW_STATE_FULLSCREEN;
1183    if (ee->engine.x.state.above)
1184      state[num++] = ECORE_X_WINDOW_STATE_ABOVE;
1185    if (ee->engine.x.state.below)
1186      state[num++] = ECORE_X_WINDOW_STATE_BELOW;
1187
1188    ecore_x_netwm_window_state_set(ee->prop.window, state, num);
1189 }
1190
1191 static void
1192 _ecore_evas_x_layer_update(Ecore_Evas *ee)
1193 {
1194    if (ee->should_be_visible)
1195      {
1196         /* We need to send a netwm request to the wm */
1197         /* FIXME: Do we have to remove old state before adding new? */
1198         if (ee->prop.layer < 3)
1199           {
1200              if (ee->engine.x.state.above)
1201                {
1202                   ee->engine.x.state.above = 0;
1203                   ecore_x_netwm_state_request_send(ee->prop.window,
1204                                                    ee->engine.x.win_root,
1205                                                    ECORE_X_WINDOW_STATE_ABOVE, -1, 0);
1206                }
1207              if (!ee->engine.x.state.below)
1208                {
1209                   ee->engine.x.state.below = 1;
1210                   ecore_x_netwm_state_request_send(ee->prop.window,
1211                                                    ee->engine.x.win_root,
1212                                                    ECORE_X_WINDOW_STATE_BELOW, -1, 1);
1213                }
1214           }
1215         else if (ee->prop.layer > 5)
1216           {
1217              if (ee->engine.x.state.below)
1218                {
1219                   ee->engine.x.state.below = 0;
1220                   ecore_x_netwm_state_request_send(ee->prop.window,
1221                                                    ee->engine.x.win_root,
1222                                                    ECORE_X_WINDOW_STATE_BELOW, -1, 0);
1223                }
1224              if (!ee->engine.x.state.above)
1225                {
1226                   ee->engine.x.state.above = 1;
1227                   ecore_x_netwm_state_request_send(ee->prop.window,
1228                                                    ee->engine.x.win_root,
1229                                                    ECORE_X_WINDOW_STATE_ABOVE, -1, 1);
1230                }
1231           }
1232         else
1233           {
1234              if (ee->engine.x.state.below)
1235                {
1236                   ee->engine.x.state.below = 0;
1237                   ecore_x_netwm_state_request_send(ee->prop.window,
1238                                                    ee->engine.x.win_root,
1239                                                    ECORE_X_WINDOW_STATE_BELOW, -1, 0);
1240                }
1241              if (ee->engine.x.state.above)
1242                {
1243                   ee->engine.x.state.above = 0;
1244                   ecore_x_netwm_state_request_send(ee->prop.window,
1245                                                    ee->engine.x.win_root,
1246                                                    ECORE_X_WINDOW_STATE_ABOVE, -1, 0);
1247                }
1248           }
1249      }
1250    else
1251      {
1252         /* Just set the state */
1253         if (ee->prop.layer < 3)
1254           {
1255              if ((ee->engine.x.state.above) || (!ee->engine.x.state.below))
1256                {
1257                   ee->engine.x.state.above = 0;
1258                   ee->engine.x.state.below = 1;
1259                   _ecore_evas_x_state_update(ee);
1260                }
1261           }
1262         else if (ee->prop.layer > 5)
1263           {
1264              if ((!ee->engine.x.state.above) || (ee->engine.x.state.below))
1265                {
1266                   ee->engine.x.state.above = 1;
1267                   ee->engine.x.state.below = 0;
1268                   _ecore_evas_x_state_update(ee);
1269                }
1270           }
1271         else
1272           {
1273              if ((ee->engine.x.state.above) || (ee->engine.x.state.below))
1274                {
1275                   ee->engine.x.state.above = 0;
1276                   ee->engine.x.state.below = 0;
1277                   _ecore_evas_x_state_update(ee);
1278                }
1279           }
1280      }
1281    /* FIXME: Set gnome layer */
1282 }
1283
1284 static int
1285 _ecore_evas_x_init(void)
1286 {
1287    _ecore_evas_init_count++;
1288    if (_ecore_evas_init_count > 1) return _ecore_evas_init_count;
1289    ecore_evas_event_handlers[0]  = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _ecore_evas_x_event_mouse_in, NULL);
1290    ecore_evas_event_handlers[1]  = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _ecore_evas_x_event_mouse_out, NULL);
1291    ecore_evas_event_handlers[2]  = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, _ecore_evas_x_event_window_focus_in, NULL);
1292    ecore_evas_event_handlers[3]  = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, _ecore_evas_x_event_window_focus_out, NULL);
1293    ecore_evas_event_handlers[4]  = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DAMAGE, _ecore_evas_x_event_window_damage, NULL);
1294    ecore_evas_event_handlers[5] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, _ecore_evas_x_event_window_destroy, NULL);
1295    ecore_evas_event_handlers[6] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _ecore_evas_x_event_window_configure, NULL);
1296    ecore_evas_event_handlers[7] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DELETE_REQUEST, _ecore_evas_x_event_window_delete_request, NULL);
1297    ecore_evas_event_handlers[8] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW, _ecore_evas_x_event_window_show, NULL);
1298    ecore_evas_event_handlers[9] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_HIDE, _ecore_evas_x_event_window_hide, NULL);
1299    ecore_evas_event_handlers[10] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, _ecore_evas_x_event_property_change, NULL);
1300    ecore_evas_event_handlers[11] = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_VISIBILITY_CHANGE, _ecore_evas_x_event_visibility_change, NULL);
1301    ecore_evas_event_handlers[12] = ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE, _ecore_evas_x_event_client_message, NULL);
1302    ecore_event_evas_init();
1303    return _ecore_evas_init_count;
1304 }
1305
1306 static void
1307 _ecore_evas_x_free(Ecore_Evas *ee)
1308 {
1309    _ecore_evas_x_group_leader_unset(ee);
1310    _ecore_evas_x_sync_set(ee);
1311    if (ee->engine.x.win_shaped_input) ecore_x_window_free(ee->engine.x.win_shaped_input);
1312    ecore_x_window_free(ee->prop.window);
1313    if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap);
1314    if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1315    if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc);
1316    if (ee->engine.x.damages) ecore_x_xregion_free(ee->engine.x.damages);
1317    ee->engine.x.pmap = 0;
1318    ee->engine.x.mask = 0;
1319    ee->engine.x.gc = 0;
1320    ee->engine.x.damages = NULL;
1321    ecore_event_window_unregister(ee->prop.window);
1322    while (ee->engine.x.win_extra)
1323      {
1324         Ecore_X_Window *winp;
1325
1326         winp = ee->engine.x.win_extra->data;
1327         ee->engine.x.win_extra = eina_list_remove_list(ee->engine.x.win_extra, ee->engine.x.win_extra);
1328         ecore_event_window_unregister(*winp);
1329         free(winp);
1330      }
1331    _ecore_evas_x_shutdown();
1332    ecore_x_shutdown();
1333 }
1334
1335 static void
1336 _ecore_evas_x_callback_delete_request_set(Ecore_Evas *ee, void (*func) (Ecore_Evas *ee))
1337 {
1338    ee->func.fn_delete_request = func;
1339    _ecore_evas_x_protocols_set(ee);
1340    _ecore_evas_x_sync_set(ee);
1341 }
1342
1343 static void
1344 _ecore_evas_x_move(Ecore_Evas *ee, int x, int y)
1345 {
1346    ee->req.x = x;
1347    ee->req.y = y;
1348    if (ee->engine.x.direct_resize)
1349      {
1350         if (!ee->engine.x.managed)
1351           {
1352              if ((x != ee->x) || (y != ee->y))
1353                {
1354                   ee->x = x;
1355                   ee->y = y;
1356                   ecore_x_window_move(ee->prop.window, x, y);
1357                   if (!ee->should_be_visible)
1358                     {
1359                        /* We need to request pos */
1360                        ee->prop.request_pos = 1;
1361                        _ecore_evas_x_size_pos_hints_update(ee);
1362                     }
1363                   if (ee->func.fn_move) ee->func.fn_move(ee);
1364                }
1365           }
1366      }
1367    else
1368      {
1369         ecore_x_window_move(ee->prop.window, x, y);
1370         if (!ee->should_be_visible)
1371           {
1372              /* We need to request pos */
1373              ee->prop.request_pos = 1;
1374              _ecore_evas_x_size_pos_hints_update(ee);
1375           }
1376         if (!ee->engine.x.managed)
1377           {
1378              ee->x = x;
1379              ee->y = y;
1380           }
1381      }
1382 }
1383
1384 static void
1385 _ecore_evas_x_managed_move(Ecore_Evas *ee, int x, int y)
1386 {
1387    ee->req.x = x;
1388    ee->req.y = y;
1389    if (ee->engine.x.direct_resize)
1390      {
1391         ee->engine.x.managed = 1;
1392         if ((x != ee->x) || (y != ee->y))
1393           {
1394              ee->x = x;
1395              ee->y = y;
1396              if (ee->func.fn_move) ee->func.fn_move(ee);
1397           }
1398      }
1399 }
1400
1401 static void
1402 _ecore_evas_x_resize(Ecore_Evas *ee, int w, int h)
1403 {
1404    ee->req.w = w;
1405    ee->req.h = h;
1406    if (ee->engine.x.direct_resize)
1407      {
1408         if ((ee->w != w) || (ee->h != h))
1409           {
1410              ecore_x_window_resize(ee->prop.window, w, h);
1411              ee->w = w;
1412              ee->h = h;
1413              if ((ee->rotation == 90) || (ee->rotation == 270))
1414                {
1415                   evas_output_size_set(ee->evas, ee->h, ee->w);
1416                   evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
1417                }
1418              else
1419                {
1420                   evas_output_size_set(ee->evas, ee->w, ee->h);
1421                   evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
1422                }
1423              if (ee->prop.avoid_damage)
1424                {
1425                   int pdam;
1426
1427                   pdam = ecore_evas_avoid_damage_get(ee);
1428                   ecore_evas_avoid_damage_set(ee, 0);
1429                   ecore_evas_avoid_damage_set(ee, pdam);
1430                }
1431              if ((ee->shaped) || (ee->alpha))
1432                _ecore_evas_x_resize_shape(ee);
1433              if (ee->func.fn_resize) ee->func.fn_resize(ee);
1434           }
1435      }
1436    else
1437      ecore_x_window_resize(ee->prop.window, w, h);
1438 }
1439
1440 static void
1441 _ecore_evas_x_move_resize(Ecore_Evas *ee, int x, int y, int w, int h)
1442 {
1443    ee->req.x = x;
1444    ee->req.y = y;
1445    ee->req.w = w;
1446    ee->req.h = h;
1447    if (ee->engine.x.direct_resize)
1448      {
1449         if ((ee->w != w) || (ee->h != h) || (x != ee->x) || (y != ee->y))
1450           {
1451              int change_size = 0, change_pos = 0;
1452
1453              if ((ee->w != w) || (ee->h != h)) change_size = 1;
1454              if (!ee->engine.x.managed)
1455                {
1456                   if ((x != ee->x) || (y != ee->y)) change_pos = 1;
1457                }
1458              ecore_x_window_move_resize(ee->prop.window, x, y, w, h);
1459              if (!ee->engine.x.managed)
1460                {
1461                   ee->x = x;
1462                   ee->y = y;
1463                }
1464              ee->w = w;
1465              ee->h = h;
1466              if ((ee->rotation == 90) || (ee->rotation == 270))
1467                {
1468                   evas_output_size_set(ee->evas, ee->h, ee->w);
1469                   evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
1470                }
1471              else
1472                {
1473                   evas_output_size_set(ee->evas, ee->w, ee->h);
1474                   evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
1475                }
1476              if (ee->prop.avoid_damage)
1477                {
1478                   int pdam;
1479
1480                   pdam = ecore_evas_avoid_damage_get(ee);
1481                   ecore_evas_avoid_damage_set(ee, 0);
1482                   ecore_evas_avoid_damage_set(ee, pdam);
1483                }
1484              if ((ee->shaped) || (ee->alpha))
1485                _ecore_evas_x_resize_shape(ee);
1486              if (change_pos)
1487                {
1488                   if (ee->func.fn_move) ee->func.fn_move(ee);
1489                }
1490              if (change_size)
1491                {
1492                   if (ee->func.fn_resize) ee->func.fn_resize(ee);
1493                }
1494           }
1495      }
1496    else
1497      {
1498         ecore_x_window_move_resize(ee->prop.window, x, y, w, h);
1499         if (!ee->engine.x.managed)
1500           {
1501              ee->x = x;
1502              ee->y = y;
1503           }
1504      }
1505 }
1506
1507 static void
1508 _ecore_evas_x_rotation_set_internal(Ecore_Evas *ee, int rotation, int resize,
1509                                     Evas_Engine_Info *einfo)
1510 {
1511    int rot_dif;
1512
1513    rot_dif = ee->rotation - rotation;
1514    if (rot_dif < 0) rot_dif = -rot_dif;
1515
1516    if (rot_dif != 180)
1517      {
1518         int minw, minh, maxw, maxh, basew, baseh, stepw, steph;
1519
1520         if (!evas_engine_info_set(ee->evas, einfo))
1521           {
1522              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1523           }
1524
1525         if (!resize)
1526           {
1527              if (!ee->prop.fullscreen)
1528                {
1529                   ecore_x_window_resize(ee->prop.window, ee->req.h, ee->req.w);
1530                   ee->expecting_resize.w = ee->h;
1531                   ee->expecting_resize.h = ee->w;
1532                }
1533              else
1534                {
1535                   int w, h;
1536
1537                   ecore_x_window_size_get(ee->prop.window, &w, &h);
1538                   ecore_x_window_resize(ee->prop.window, h, w);
1539                   if ((rotation == 0) || (rotation == 180))
1540                     {
1541                        evas_output_size_set(ee->evas, ee->req.w, ee->req.h);
1542                        evas_output_viewport_set(ee->evas, 0, 0, ee->req.w, ee->req.h);
1543                     }
1544                   else
1545                     {
1546                        evas_output_size_set(ee->evas, ee->req.h, ee->req.w);
1547                        evas_output_viewport_set(ee->evas, 0, 0, ee->req.h, ee->req.w);
1548                     }
1549                   if (ee->func.fn_resize) ee->func.fn_resize(ee);
1550                }
1551              if ((ee->rotation == 90) || (ee->rotation == 270))
1552                evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.h, ee->req.w);
1553              else
1554                evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
1555           }
1556         else
1557           {
1558              int w, h;
1559
1560              ecore_x_window_size_get(ee->prop.window, &w, &h);
1561              if ((rotation == 0) || (rotation == 180))
1562                {
1563                   evas_output_size_set(ee->evas, ee->w, ee->h);
1564                   evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
1565                }
1566              else
1567                {
1568                   evas_output_size_set(ee->evas, ee->h, ee->w);
1569                   evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
1570                }
1571              if (ee->func.fn_resize) ee->func.fn_resize(ee);
1572              if ((ee->rotation == 90) || (ee->rotation == 270))
1573                evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
1574              else
1575                evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1576           }
1577         ecore_evas_size_min_get(ee, &minw, &minh);
1578         ecore_evas_size_max_get(ee, &maxw, &maxh);
1579         ecore_evas_size_base_get(ee, &basew, &baseh);
1580         ecore_evas_size_step_get(ee, &stepw, &steph);
1581         ee->rotation = rotation;
1582         ecore_evas_size_min_set(ee, minh, minw);
1583         ecore_evas_size_max_set(ee, maxh, maxw);
1584         ecore_evas_size_base_set(ee, baseh, basew);
1585         ecore_evas_size_step_set(ee, steph, stepw);
1586         _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y,
1587                                        ecore_x_current_time_get());
1588      }
1589    else
1590      {
1591         if (!evas_engine_info_set(ee->evas, einfo))
1592           {
1593              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1594           }
1595         ee->rotation = rotation;
1596         _ecore_evas_mouse_move_process(ee, ee->mouse.x, ee->mouse.y,
1597                                        ecore_x_current_time_get());
1598         if (ee->func.fn_resize) ee->func.fn_resize(ee);
1599
1600         if ((ee->rotation == 90) || (ee->rotation == 270))
1601           evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
1602         else
1603           evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1604      }
1605 }
1606
1607 #define _USE_WIN_ROT_EFFECT 1
1608
1609 #if _USE_WIN_ROT_EFFECT
1610 static void _ecore_evas_x_flush_pre(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__);
1611
1612 typedef struct _Ecore_Evas_X_Rotation_Effect Ecore_Evas_X_Rotation_Effect;
1613 struct _Ecore_Evas_X_Rotation_Effect
1614 {
1615    Eina_Bool    wait_for_comp_reply;
1616 };
1617
1618 static Ecore_Evas_X_Rotation_Effect _rot_effect =
1619 {
1620    EINA_FALSE
1621 };
1622
1623 static void
1624 _ecore_evas_x_rotation_effect_setup(void)
1625 {
1626    _rot_effect.wait_for_comp_reply = EINA_TRUE;
1627 }
1628 #endif /* end of _USE_WIN_ROT_EFFECT */
1629
1630 static void
1631 _ecore_evas_x_rotation_set(Ecore_Evas *ee, int rotation, int resize)
1632 {
1633    if (ee->rotation == rotation) return;
1634    if (!strcmp(ee->driver, "xrender_x11")) return;
1635
1636 #if _USE_WIN_ROT_EFFECT
1637    int angles[2];
1638    angles[0] = rotation;
1639    angles[1] = ee->rotation;
1640 #endif /* end of _USE_WIN_ROT_EFFECT */
1641
1642    if (!strcmp(ee->driver, "opengl_x11"))
1643      {
1644 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
1645         Evas_Engine_Info_GL_X11 *einfo;
1646
1647         einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
1648         if (!einfo) return;
1649         einfo->info.rotation = rotation;
1650         _ecore_evas_x_rotation_set_internal
1651           (ee, rotation, resize, (Evas_Engine_Info *)einfo);
1652 # if _USE_WIN_ROT_EFFECT
1653        ecore_x_window_prop_property_set (ee->prop.window,
1654                                          ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
1655                                          ECORE_X_ATOM_CARDINAL, 32, &angles, 2);
1656 # else
1657        ecore_x_window_prop_property_set (ee->prop.window,
1658                                          ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
1659                                          ECORE_X_ATOM_CARDINAL, 32, &rotation, 1);
1660 # endif
1661 #endif /* BUILD_ECORE_EVAS_OPENGL_X11 */
1662      }
1663    else if (!strcmp(ee->driver, "software_x11"))
1664      {
1665 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
1666         Evas_Engine_Info_Software_X11 *einfo;
1667
1668         einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
1669         if (!einfo) return;
1670         einfo->info.rotation = rotation;
1671         _ecore_evas_x_rotation_set_internal
1672           (ee, rotation, resize, (Evas_Engine_Info *)einfo);
1673 # if _USE_WIN_ROT_EFFECT
1674        ecore_x_window_prop_property_set (ee->prop.window,
1675                                          ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
1676                                          ECORE_X_ATOM_CARDINAL, 32, &angles, 2);
1677 # else
1678        ecore_x_window_prop_property_set (ee->prop.window,
1679                                          ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
1680                                          ECORE_X_ATOM_CARDINAL, 32, &rotation, 1);
1681 # endif
1682 #endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
1683      }
1684    else if (!strcmp(ee->driver,  "software_16_x11"))
1685      {
1686 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
1687         Evas_Engine_Info_Software_16_X11 *einfo;
1688
1689         einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
1690         if (!einfo) return;
1691         einfo->info.rotation = rotation;
1692         _ecore_evas_x_rotation_set_internal
1693           (ee, rotation, resize, (Evas_Engine_Info *)einfo);
1694 # if _USE_WIN_ROT_EFFECT
1695        ecore_x_window_prop_property_set (ee->prop.window,
1696                                          ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
1697                                          ECORE_X_ATOM_CARDINAL, 32, &angles, 2);
1698 # else
1699        ecore_x_window_prop_property_set (ee->prop.window,
1700                                          ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
1701                                          ECORE_X_ATOM_CARDINAL, 32, &rotation, 1);
1702 # endif
1703 #endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
1704      }
1705    else if (!strcmp(ee->driver,  "software_8_x11"))
1706      {
1707 #if BUILD_ECORE_EVAS_SOFTWARE_8_X11
1708         Evas_Engine_Info_Software_8_X11 *einfo;
1709
1710         einfo = (Evas_Engine_Info_Software_8_X11 *)evas_engine_info_get(ee->evas);
1711         if (!einfo) return;
1712         einfo->info.rotation = rotation;
1713         _ecore_evas_x_rotation_set_internal
1714            (ee, rotation, resize, (Evas_Engine_Info *)einfo);
1715 # if _USE_WIN_ROT_EFFECT
1716        ecore_x_window_prop_property_set (ee->prop.window,
1717                                          ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
1718                                          ECORE_X_ATOM_CARDINAL, 32, &angles, 2);
1719 # else
1720        ecore_x_window_prop_property_set (ee->prop.window,
1721                                          ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE,
1722                                          ECORE_X_ATOM_CARDINAL, 32, &rotation, 1);
1723 # endif
1724 #endif /* BUILD_ECORE_EVAS_SOFTWARE_8_X11 */
1725      }
1726
1727 #if _USE_WIN_ROT_EFFECT
1728   _ecore_evas_x_rotation_effect_setup();
1729   _ecore_evas_x_flush_pre(ee, NULL, NULL);
1730 #endif /* end of _USE_WIN_ROT_EFFECT */
1731 }
1732
1733 static void
1734 _ecore_evas_x_shaped_set(Ecore_Evas *ee, int shaped)
1735 {
1736    if (((ee->shaped) && (shaped)) || ((!ee->shaped) && (!shaped)))
1737      return;
1738    if (!strcmp(ee->driver, "opengl_x11")) return;
1739    if (!strcmp(ee->driver, "software_x11"))
1740      {
1741 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
1742         Evas_Engine_Info_Software_X11 *einfo;
1743
1744         einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
1745         ee->shaped = shaped;
1746         if (einfo)
1747           {
1748              if (ee->shaped)
1749                {
1750                   unsigned int    foreground;
1751                   Ecore_X_GC      gc;
1752
1753                   if (!ee->engine.x.mask)
1754                     ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
1755                   foreground = 0;
1756                   gc = ecore_x_gc_new(ee->engine.x.mask,
1757                                       ECORE_X_GC_VALUE_MASK_FOREGROUND,
1758                                       &foreground);
1759                   ecore_x_drawable_rectangle_fill(ee->engine.x.mask, gc,
1760                                                   0, 0, ee->w, ee->h);
1761                   ecore_x_gc_free(gc);
1762                   einfo->info.mask = ee->engine.x.mask;
1763                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1764                     {
1765                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1766                     }
1767                   evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1768                   ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1769                }
1770              else
1771                {
1772                   if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1773                   ee->engine.x.mask = 0;
1774                   einfo->info.mask = 0;
1775                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1776                     {
1777                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1778                     }
1779                   ecore_x_window_shape_mask_set(ee->prop.window, 0);
1780                   ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1781                }
1782           }
1783 #endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
1784      }
1785    else if (!strcmp(ee->driver, "xrender_x11"))
1786      {
1787 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
1788         Evas_Engine_Info_XRender_X11 *einfo;
1789
1790         ee->shaped = shaped;
1791         einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
1792         if (einfo)
1793           {
1794              if (ee->shaped)
1795                {
1796                   unsigned int    foreground;
1797                   Ecore_X_GC      gc;
1798
1799                   if (!ee->engine.x.mask)
1800                     ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
1801                   foreground = 0;
1802                   gc = ecore_x_gc_new(ee->engine.x.mask,
1803                                       ECORE_X_GC_VALUE_MASK_FOREGROUND,
1804                                       &foreground);
1805                   ecore_x_drawable_rectangle_fill(ee->engine.x.mask, gc,
1806                                                   0, 0, ee->w, ee->h);
1807                   ecore_x_gc_free(gc);
1808                   einfo->info.mask = ee->engine.x.mask;
1809                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1810                     {
1811                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1812                     }
1813                   evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1814                   ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1815                }
1816              else
1817                {
1818                   if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1819                   ee->engine.x.mask = 0;
1820                   einfo->info.mask = 0;
1821                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1822                     {
1823                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1824                     }
1825                   ecore_x_window_shape_mask_set(ee->prop.window, 0);
1826                   ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1827                }
1828           }
1829 #endif /* BUILD_ECORE_EVAS_XRENDER_X11 || BUILD_ECORE_EVAS_XRENDER_XCB */
1830      }
1831    else if (!strcmp(ee->driver, "software_16_x11"))
1832      {
1833 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
1834 # if 0 /* XXX no shaped window support for software_16_x11 */
1835         Evas_Engine_Info_Software_16_X11 *einfo;
1836
1837         einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
1838         ee->shaped = shaped;
1839         if (einfo)
1840           {
1841              if (ee->shaped)
1842                {
1843                   GC gc;
1844                   XGCValues gcv;
1845
1846                   ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
1847                   einfo->info.mask = ee->engine.x.mask;
1848                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1849                     {
1850                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1851                     }
1852                   evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1853                }
1854              else
1855                {
1856                   if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1857                   ee->engine.x.mask = 0;
1858                   einfo->info.mask = 0;
1859                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1860                     {
1861                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1862                     }
1863                   ecore_x_window_shape_mask_set(ee->prop.window, 0);
1864                }
1865           }
1866 # endif /* XXX no shaped window support for software_16_x11 */
1867 #endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
1868      }
1869    if (!strcmp(ee->driver, "software_8_x11"))
1870      {
1871 #if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
1872         Evas_Engine_Info_Software_8_X11 *einfo;
1873
1874         einfo = (Evas_Engine_Info_Software_8_X11 *)evas_engine_info_get(ee->evas);
1875         ee->shaped = shaped;
1876         if (einfo)
1877           {
1878              if (ee->shaped)
1879                {
1880                   unsigned int    foreground;
1881                   Ecore_X_GC      gc;
1882
1883                   if (!ee->engine.x.mask)
1884                     ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
1885                   foreground = 0;
1886                   gc = ecore_x_gc_new(ee->engine.x.mask,
1887                                       ECORE_X_GC_VALUE_MASK_FOREGROUND,
1888                                       &foreground);
1889                   ecore_x_drawable_rectangle_fill(ee->engine.x.mask, gc,
1890                                                   0, 0, ee->w, ee->h);
1891                   ecore_x_gc_free(gc);
1892                   einfo->info.mask = ee->engine.x.mask;
1893                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1894                     {
1895                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1896                     }
1897                   evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1898                   ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1899                }
1900              else
1901                {
1902                   if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1903                   ee->engine.x.mask = 0;
1904                   einfo->info.mask = 0;
1905                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1906                     {
1907                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1908                     }
1909                   ecore_x_window_shape_mask_set(ee->prop.window, 0);
1910                   ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1911                }
1912           }
1913 #endif /* BUILD_ECORE_EVAS_SOFTWARE_8_X11 */
1914      }
1915 }
1916
1917 /* FIXME, round trip */
1918 static void
1919 _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha)
1920 {
1921 # ifdef HAVE_ECORE_X_XCB
1922    xcb_get_geometry_cookie_t          cookie_geom;
1923    xcb_get_window_attributes_cookie_t cookie_attr;
1924    xcb_get_geometry_reply_t          *reply_geom;
1925    xcb_get_window_attributes_reply_t *reply_attr;
1926 #else
1927    XWindowAttributes att;
1928 #endif /* ! HAVE_ECORE_X_XCB */
1929
1930    if (((ee->alpha) && (alpha)) || ((!ee->alpha) && (!alpha)))
1931      return;
1932
1933    if (!strcmp(ee->driver, "software_x11"))
1934      {
1935 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
1936         Evas_Engine_Info_Software_X11 *einfo;
1937
1938         einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
1939         if (!einfo) return;
1940
1941         if (!ecore_x_composite_query()) return;
1942
1943         ee->shaped = 0;
1944         ee->alpha = alpha;
1945         ecore_x_window_free(ee->prop.window);
1946         ecore_event_window_unregister(ee->prop.window);
1947         if (ee->alpha)
1948           {
1949              if (ee->prop.override)
1950                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);
1951              else
1952                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);
1953              if (!ee->engine.x.mask)
1954                ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
1955           }
1956         else
1957           {
1958              if (ee->prop.override)
1959                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);
1960              else
1961                ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
1962              if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1963              ee->engine.x.mask = 0;
1964              ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1965           }
1966
1967         einfo->info.destination_alpha = alpha;
1968
1969 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
1970         cookie_geom = xcb_get_geometry_unchecked(ecore_x_connection_get(), ee->prop.window);
1971         cookie_attr = xcb_get_window_attributes_unchecked(ecore_x_connection_get(), ee->prop.window);
1972
1973         reply_geom = xcb_get_geometry_reply(ecore_x_connection_get(), cookie_geom, NULL);
1974         reply_attr = xcb_get_window_attributes_reply(ecore_x_connection_get(), cookie_attr, NULL);
1975         einfo->info.visual = xcb_visualtype_get(ecore_x_default_screen_get(), reply_attr->visual);
1976         einfo->info.colormap = reply_attr->colormap;
1977         einfo->info.depth = reply_geom->depth;
1978         free(reply_geom);
1979         free(reply_attr);
1980 # else
1981         XGetWindowAttributes(ecore_x_display_get(), ee->prop.window, &att);
1982         einfo->info.visual = att.visual;
1983         einfo->info.colormap = att.colormap;
1984         einfo->info.depth = att.depth;
1985 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
1986
1987 //        if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1988 //        ee->engine.x.mask = 0;
1989         einfo->info.mask = ee->engine.x.mask;
1990         einfo->info.drawable = ee->prop.window;
1991         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
1992           {
1993              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
1994           }
1995         evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
1996         ecore_x_window_shape_mask_set(ee->prop.window, 0);
1997         ecore_x_input_multi_select(ee->prop.window);
1998         ecore_event_window_register(ee->prop.window, ee, ee->evas,
1999                                     (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
2000                                     (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
2001                                     (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
2002                                     (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
2003         if (ee->prop.borderless)
2004           ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
2005         if (ee->visible) ecore_x_window_show(ee->prop.window);
2006         if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
2007         if (ee->prop.title)
2008           {
2009              ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
2010              ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
2011           }
2012         ecore_x_icccm_hints_set(ee->prop.window,
2013                                 1 /* accepts_focus */,
2014                                 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2015                                 0 /* icon_pixmap */,
2016                                 0 /* icon_mask */,
2017                                 0 /* icon_window */,
2018                                 0 /* window_group */,
2019                                 0 /* is_urgent */);
2020         _ecore_evas_x_group_leader_update(ee);
2021         ecore_x_window_defaults_set(ee->prop.window);
2022         _ecore_evas_x_protocols_set(ee);
2023         _ecore_evas_x_sync_set(ee);
2024 #endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
2025         if (getenv("DESKTOP_STARTUP_ID"))
2026           {
2027              ecore_x_netwm_startup_id_set(ee->prop.window,
2028                                           getenv("DESKTOP_STARTUP_ID"));
2029              /* NB: on linux this may simply empty the env as opposed to completely
2030               * unset it to being empty - unsure as solartis libc crashes looking
2031               * for the '=' char */
2032              //        putenv((char*)"DESKTOP_STARTUP_ID=");
2033           }
2034      }
2035    else if (!strcmp(ee->driver, "opengl_x11"))
2036      {
2037 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
2038         Evas_Engine_Info_GL_X11 *einfo;
2039
2040         einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
2041         if (!einfo) return;
2042
2043         if (!ecore_x_composite_query()) return;
2044
2045         ee->shaped = 0;
2046         ee->alpha = alpha;
2047         ecore_x_window_free(ee->prop.window);
2048         ecore_event_window_unregister(ee->prop.window);
2049         ee->prop.window = 0;
2050
2051         einfo->info.destination_alpha = alpha;
2052
2053         if (ee->engine.x.win_root != 0)
2054           {
2055              /* FIXME: round trip in ecore_x_window_argb_get */
2056              if (ecore_x_window_argb_get(ee->engine.x.win_root))
2057                {
2058                   ee->prop.window = _ecore_evas_x_gl_window_new
2059                     (ee, ee->engine.x.win_root,
2060                      ee->req.x, ee->req.y, ee->req.w, ee->req.h,
2061                      ee->prop.override, 1, NULL);
2062                }
2063              else
2064                ee->prop.window = _ecore_evas_x_gl_window_new
2065                (ee, ee->engine.x.win_root,
2066                 ee->req.x, ee->req.y, ee->req.w, ee->req.h,
2067                 ee->prop.override, ee->alpha, NULL);
2068           }
2069         else
2070           ee->prop.window = _ecore_evas_x_gl_window_new
2071           (ee, ee->engine.x.win_root,
2072            ee->req.x, ee->req.y, ee->req.w, ee->req.h,
2073            ee->prop.override, ee->alpha, NULL);
2074         if (!ee->prop.window)
2075           {
2076              return;
2077           }
2078 /*
2079         if (ee->alpha)
2080           {
2081              if (ee->prop.override)
2082                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);
2083              else
2084                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);
2085              if (!ee->engine.x.mask)
2086                ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
2087           }
2088         else
2089           {
2090              if (ee->prop.override)
2091                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);
2092              else
2093                ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
2094              if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
2095              ee->engine.x.mask = 0;
2096              ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
2097           }
2098  */
2099
2100         XGetWindowAttributes(ecore_x_display_get(), ee->prop.window, &att);
2101         einfo->info.visual = att.visual;
2102         einfo->info.colormap = att.colormap;
2103         einfo->info.depth = att.depth;
2104
2105 //        if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
2106 //        ee->engine.x.mask = 0;
2107 //        einfo->info.mask = ee->engine.x.mask;
2108         einfo->info.drawable = ee->prop.window;
2109         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2110           {
2111              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2112           }
2113         evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
2114 //        ecore_x_window_shape_mask_set(ee->prop.window, 0);
2115         ecore_x_input_multi_select(ee->prop.window);
2116         ecore_event_window_register(ee->prop.window, ee, ee->evas,
2117                                     (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
2118                                     (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
2119                                     (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
2120                                     (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
2121         if (ee->prop.borderless)
2122           ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
2123         if (ee->visible) ecore_x_window_show(ee->prop.window);
2124         if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
2125         if (ee->prop.title)
2126           {
2127              ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
2128              ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
2129           }
2130         ecore_x_icccm_hints_set(ee->prop.window,
2131                                 1 /* accepts_focus */,
2132                                 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2133                                 0 /* icon_pixmap */,
2134                                 0 /* icon_mask */,
2135                                 0 /* icon_window */,
2136                                 0 /* window_group */,
2137                                 0 /* is_urgent */);
2138         _ecore_evas_x_group_leader_update(ee);
2139         ecore_x_window_defaults_set(ee->prop.window);
2140         _ecore_evas_x_protocols_set(ee);
2141         _ecore_evas_x_sync_set(ee);
2142 #endif /* BUILD_ECORE_EVAS_OPENGL_X11 */
2143         if (getenv("DESKTOP_STARTUP_ID"))
2144           {
2145              ecore_x_netwm_startup_id_set(ee->prop.window,
2146                                           getenv("DESKTOP_STARTUP_ID"));
2147              /* NB: on linux this may simply empty the env as opposed to completely
2148               * unset it to being empty - unsure as solartis libc crashes looking
2149               * for the '=' char */
2150              //        putenv((char*)"DESKTOP_STARTUP_ID=");
2151           }
2152      }
2153    else if (!strcmp(ee->driver, "xrender_x11"))
2154      {
2155 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
2156         Evas_Engine_Info_XRender_X11 *einfo;
2157
2158         einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
2159         if (!einfo) return;
2160         if (!ecore_x_composite_query()) return;
2161
2162         ee->shaped = 0;
2163         ee->alpha = alpha;
2164         ecore_x_window_free(ee->prop.window);
2165         ecore_event_window_unregister(ee->prop.window);
2166         if (ee->alpha)
2167           {
2168              if (ee->prop.override)
2169                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);
2170              else
2171                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);
2172              if (!ee->engine.x.mask)
2173                ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
2174           }
2175         else
2176           {
2177              if (ee->prop.override)
2178                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);
2179              else
2180                ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
2181              if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
2182              ee->engine.x.mask = 0;
2183              ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
2184           }
2185
2186         einfo->info.destination_alpha = alpha;
2187
2188 # ifdef BUILD_ECORE_EVAS_XRENDER_XCB
2189         cookie_attr = xcb_get_window_attributes_unchecked(ecore_x_connection_get(), ee->prop.window);
2190         reply_attr = xcb_get_window_attributes_reply(ecore_x_connection_get(), cookie_attr, NULL);
2191
2192         einfo->info.visual = reply_attr->visual;
2193         free(reply_attr);
2194 # else
2195         XGetWindowAttributes(ecore_x_display_get(), ee->prop.window, &att);
2196         einfo->info.visual = att.visual;
2197 # endif /* ! BUILD_ECORE_EVAS_XRENDER_XCB */
2198
2199 //        if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
2200 //        ee->engine.x.mask = 0;
2201         einfo->info.mask = ee->engine.x.mask;
2202         einfo->info.drawable = ee->prop.window;
2203         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2204           {
2205              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2206           }
2207         evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
2208         ecore_x_window_shape_mask_set(ee->prop.window, 0);
2209         ecore_x_input_multi_select(ee->prop.window);
2210         ecore_event_window_register(ee->prop.window, ee, ee->evas,
2211                                     (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
2212                                     (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
2213                                     (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
2214                                     (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
2215         if (ee->prop.borderless)
2216           ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
2217         if (ee->visible) ecore_x_window_show(ee->prop.window);
2218         if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
2219         if (ee->prop.title)
2220           {
2221              ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
2222              ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
2223           }
2224         ecore_x_icccm_hints_set(ee->prop.window,
2225                                 1 /* accepts_focus */,
2226                                 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2227                                 0 /* icon_pixmap */,
2228                                 0 /* icon_mask */,
2229                                 0 /* icon_window */,
2230                                 0 /* window_group */,
2231                                 0 /* is_urgent */);
2232         _ecore_evas_x_group_leader_update(ee);
2233         ecore_x_window_defaults_set(ee->prop.window);
2234         _ecore_evas_x_protocols_set(ee);
2235         _ecore_evas_x_sync_set(ee);
2236 #endif /* BUILD_ECORE_EVAS_XRENDER_X11 || BUILD_ECORE_EVAS_XRENDER_XCB */
2237         if (getenv("DESKTOP_STARTUP_ID"))
2238           {
2239              ecore_x_netwm_startup_id_set(ee->prop.window,
2240                                           getenv("DESKTOP_STARTUP_ID"));
2241              /* NB: on linux this may simply empty the env as opposed to completely
2242               * unset it to being empty - unsure as solartis libc crashes looking
2243               * for the '=' char */
2244              //        putenv((char*)"DESKTOP_STARTUP_ID=");
2245           }
2246      }
2247    else if (!strcmp(ee->driver, "software_16_x11"))
2248      {
2249 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
2250         Evas_Engine_Info_Software_16_X11 *einfo;
2251
2252         einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
2253         if (!einfo) return;
2254
2255         ee->shaped = 0;
2256         ee->alpha = alpha;
2257         ecore_x_window_free(ee->prop.window);
2258         ecore_event_window_unregister(ee->prop.window);
2259         if (ee->alpha)
2260           {
2261              if (ee->prop.override)
2262                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);
2263              else
2264                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);
2265              if (!ee->engine.x.mask)
2266                ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
2267           }
2268         else
2269           {
2270              if (ee->prop.override)
2271                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);
2272              else
2273                ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
2274              if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
2275              ee->engine.x.mask = 0;
2276              ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
2277           }
2278
2279 # if 0 /* XXX no alpha window support for software_16_x11 */
2280         einfo->info.destination_alpha = alpha;
2281 # endif /* XXX no alpha window support for software_16_x11 */
2282
2283 # if 0 /* XXX no shaped window support for software_16_x11 */
2284 //        if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
2285 //        ee->engine.x.mask = 0;
2286         einfo->info.mask = ee->engine.x.mask;
2287 # endif /* XXX no shaped window support for software_16_x11 */
2288
2289         einfo->info.drawable = ee->prop.window;
2290         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2291           {
2292              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2293           }
2294         evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
2295         ecore_x_window_shape_mask_set(ee->prop.window, 0);
2296         ecore_x_input_multi_select(ee->prop.window);
2297         ecore_event_window_register(ee->prop.window, ee, ee->evas,
2298                                     (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
2299                                     (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
2300                                     (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
2301                                     (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
2302         if (ee->prop.borderless)
2303           ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
2304         if (ee->visible) ecore_x_window_show(ee->prop.window);
2305         if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
2306         if (ee->prop.title)
2307           {
2308              ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
2309              ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
2310           }
2311         ecore_x_icccm_hints_set(ee->prop.window,
2312                                 1 /* accepts_focus */,
2313                                 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2314                                 0 /* icon_pixmap */,
2315                                 0 /* icon_mask */,
2316                                 0 /* icon_window */,
2317                                 0 /* window_group */,
2318                                 0 /* is_urgent */);
2319         _ecore_evas_x_group_leader_update(ee);
2320         ecore_x_window_defaults_set(ee->prop.window);
2321         _ecore_evas_x_protocols_set(ee);
2322         _ecore_evas_x_sync_set(ee);
2323 #endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
2324         if (getenv("DESKTOP_STARTUP_ID"))
2325           {
2326              ecore_x_netwm_startup_id_set(ee->prop.window,
2327                                           getenv("DESKTOP_STARTUP_ID"));
2328              /* NB: on linux this may simply empty the env as opposed to completely
2329               * unset it to being empty - unsure as solartis libc crashes looking
2330               * for the '=' char */
2331              //        putenv((char*)"DESKTOP_STARTUP_ID=");
2332           }
2333      }
2334    else if (!strcmp(ee->driver, "software_8_x11"))
2335      {
2336 #if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
2337         Evas_Engine_Info_Software_8_X11 *einfo;
2338
2339         einfo = (Evas_Engine_Info_Software_8_X11 *)evas_engine_info_get(ee->evas);
2340         if (!einfo) return;
2341
2342         ee->shaped = 0;
2343         ee->alpha = alpha;
2344         ecore_x_window_free(ee->prop.window);
2345         ecore_event_window_unregister(ee->prop.window);
2346         if (ee->alpha)
2347           {
2348              if (ee->prop.override)
2349                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);
2350              else
2351                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);
2352              if (!ee->engine.x.mask)
2353                ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->req.w, ee->req.h, 1);
2354           }
2355         else
2356           {
2357              if (ee->prop.override)
2358                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);
2359              else
2360                ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->req.x, ee->req.y, ee->req.w, ee->req.h);
2361              if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
2362              ee->engine.x.mask = 0;
2363              ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
2364           }
2365
2366         einfo->info.destination_alpha = alpha;
2367
2368         cookie_geom = xcb_get_geometry_unchecked(ecore_x_connection_get(), ee->prop.window);
2369         cookie_attr = xcb_get_window_attributes_unchecked(ecore_x_connection_get(), ee->prop.window);
2370
2371         reply_geom = xcb_get_geometry_reply(ecore_x_connection_get(), cookie_geom, NULL);
2372         reply_attr = xcb_get_window_attributes_reply(ecore_x_connection_get(), cookie_attr, NULL);
2373         einfo->info.visual = xcb_visualtype_get(ecore_x_default_screen_get(), reply_attr->visual);
2374         einfo->info.colormap = reply_attr->colormap;
2375         einfo->info.depth = reply_geom->depth;
2376         free(reply_geom);
2377         free(reply_attr);
2378
2379 //        if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
2380 //        ee->engine.x.mask = 0;
2381         einfo->info.mask = ee->engine.x.mask;
2382         einfo->info.drawable = ee->prop.window;
2383         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2384           {
2385              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2386           }
2387         evas_damage_rectangle_add(ee->evas, 0, 0, ee->req.w, ee->req.h);
2388         ecore_x_window_shape_mask_set(ee->prop.window, 0);
2389         ecore_x_input_multi_select(ee->prop.window);
2390         ecore_event_window_register(ee->prop.window, ee, ee->evas,
2391                                     (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
2392                                     (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
2393                                     (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
2394                                     (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
2395         if (ee->prop.borderless)
2396           ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
2397         if (ee->visible) ecore_x_window_show(ee->prop.window);
2398         if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
2399         if (ee->prop.title)
2400           {
2401              ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
2402              ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
2403           }
2404         ecore_x_icccm_hints_set(ee->prop.window,
2405                                 1 /* accepts_focus */,
2406                                 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2407                                 0 /* icon_pixmap */,
2408                                 0 /* icon_mask */,
2409                                 0 /* icon_window */,
2410                                 0 /* window_group */,
2411                                 0 /* is_urgent */);
2412         _ecore_evas_x_group_leader_update(ee);
2413         ecore_x_window_defaults_set(ee->prop.window);
2414         _ecore_evas_x_protocols_set(ee);
2415         _ecore_evas_x_sync_set(ee);
2416
2417         if (getenv("DESKTOP_STARTUP_ID"))
2418           {
2419              ecore_x_netwm_startup_id_set(ee->prop.window,
2420                                           getenv("DESKTOP_STARTUP_ID"));
2421              /* NB: on linux this may simply empty the env as opposed to completely
2422               * unset it to being empty - unsure as solartis libc crashes looking
2423               * for the '=' char */
2424              //        putenv((char*)"DESKTOP_STARTUP_ID=");
2425           }
2426 #endif /* BUILD_ECORE_EVAS_SOFTWARE_8_X11 */
2427      }
2428 }
2429
2430 static void
2431 _ecore_evas_x_transparent_set(Ecore_Evas *ee, int transparent)
2432 {
2433    if (((ee->transparent) && (transparent)) ||
2434        ((!ee->transparent) && (!transparent)))
2435      return;
2436
2437    if (!strcmp(ee->driver, "software_x11"))
2438      {
2439 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
2440         Evas_Engine_Info_Software_X11 *einfo;
2441
2442         einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
2443         if (!einfo) return;
2444
2445         ee->transparent = transparent;
2446         einfo->info.destination_alpha = transparent;
2447         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2448           {
2449              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2450           }
2451         evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
2452 #endif
2453      }
2454 }
2455 #endif /* BUILD_ECORE_EVAS_X11 */
2456
2457 #ifdef BUILD_ECORE_EVAS_X11
2458 static void
2459 _ecore_evas_x_show(Ecore_Evas *ee)
2460 {
2461    ee->should_be_visible = 1;
2462    if (ee->prop.avoid_damage)
2463      _ecore_evas_x_render(ee);
2464    _ecore_evas_x_sync_set(ee);
2465    ecore_x_window_show(ee->prop.window);
2466    if (ee->prop.fullscreen)
2467      ecore_x_window_focus(ee->prop.window);
2468 }
2469
2470 static void
2471 _ecore_evas_x_hide(Ecore_Evas *ee)
2472 {
2473    ecore_x_window_hide(ee->prop.window);
2474    ee->should_be_visible = 0;
2475    _ecore_evas_x_sync_set(ee);
2476 }
2477
2478 static void
2479 _ecore_evas_x_raise(Ecore_Evas *ee)
2480 {
2481    if (!ee->prop.fullscreen)
2482      ecore_x_window_raise(ee->prop.window);
2483    else
2484      ecore_x_window_raise(ee->prop.window);
2485 }
2486
2487 static void
2488 _ecore_evas_x_lower(Ecore_Evas *ee)
2489 {
2490    if (!ee->prop.fullscreen)
2491      ecore_x_window_lower(ee->prop.window);
2492    else
2493      ecore_x_window_lower(ee->prop.window);
2494 }
2495
2496 static void
2497 _ecore_evas_x_activate(Ecore_Evas *ee)
2498 {
2499    ecore_x_netwm_client_active_request(ee->engine.x.win_root,
2500                                        ee->prop.window, 2, 0);
2501 }
2502
2503 static void
2504 _ecore_evas_x_title_set(Ecore_Evas *ee, const char *t)
2505 {
2506    if (ee->prop.title) free(ee->prop.title);
2507    ee->prop.title = NULL;
2508    if (t) ee->prop.title = strdup(t);
2509    ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
2510    ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
2511 }
2512
2513 static void
2514 _ecore_evas_x_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
2515 {
2516    if (ee->prop.name) free(ee->prop.name);
2517    if (ee->prop.clas) free(ee->prop.clas);
2518    ee->prop.name = NULL;
2519    ee->prop.clas = NULL;
2520    if (n) ee->prop.name = strdup(n);
2521    if (c) ee->prop.clas = strdup(c);
2522    ecore_x_icccm_name_class_set(ee->prop.window, ee->prop.name, ee->prop.clas);
2523 }
2524
2525 static void
2526 _ecore_evas_x_size_min_set(Ecore_Evas *ee, int w, int h)
2527 {
2528    if (w < 0) w = 0;
2529    if (h < 0) h = 0;
2530    if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return;
2531    ee->prop.min.w = w;
2532    ee->prop.min.h = h;
2533    _ecore_evas_x_size_pos_hints_update(ee);
2534 }
2535
2536 static void
2537 _ecore_evas_x_size_max_set(Ecore_Evas *ee, int w, int h)
2538 {
2539    if (w < 0) w = 0;
2540    if (h < 0) h = 0;
2541    if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return;
2542    ee->prop.max.w = w;
2543    ee->prop.max.h = h;
2544    _ecore_evas_x_size_pos_hints_update(ee);
2545 }
2546
2547 static void
2548 _ecore_evas_x_size_base_set(Ecore_Evas *ee, int w, int h)
2549 {
2550    if (w < 0) w = 0;
2551    if (h < 0) h = 0;
2552    if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return;
2553    ee->prop.base.w = w;
2554    ee->prop.base.h = h;
2555    _ecore_evas_x_size_pos_hints_update(ee);
2556 }
2557
2558 static void
2559 _ecore_evas_x_size_step_set(Ecore_Evas *ee, int w, int h)
2560 {
2561    if (w < 1) w = 1;
2562    if (h < 1) h = 1;
2563    if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return;
2564    ee->prop.step.w = w;
2565    ee->prop.step.h = h;
2566    _ecore_evas_x_size_pos_hints_update(ee);
2567 }
2568
2569 static void
2570 _ecore_evas_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2571 {
2572    Ecore_Evas *ee;
2573
2574    ee = data;
2575    if (ee)
2576      ee->prop.cursor.object = NULL;
2577 }
2578
2579 static void
2580 _ecore_evas_x_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
2581 {
2582    int x, y;
2583
2584    if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
2585
2586    if (!obj)
2587      {
2588         ee->prop.cursor.object = NULL;
2589         ee->prop.cursor.layer = 0;
2590         ee->prop.cursor.hot.x = 0;
2591         ee->prop.cursor.hot.y = 0;
2592         ecore_x_window_cursor_show(ee->prop.window, 1);
2593         return;
2594      }
2595
2596    ee->prop.cursor.object = obj;
2597    ee->prop.cursor.layer = layer;
2598    ee->prop.cursor.hot.x = hot_x;
2599    ee->prop.cursor.hot.y = hot_y;
2600
2601    ecore_x_window_cursor_show(ee->prop.window, 0);
2602
2603    evas_pointer_output_xy_get(ee->evas, &x, &y);
2604    evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
2605    evas_object_move(ee->prop.cursor.object,
2606                     x - ee->prop.cursor.hot.x,
2607                     y - ee->prop.cursor.hot.y);
2608    evas_object_pass_events_set(ee->prop.cursor.object, 1);
2609    if (evas_pointer_inside_get(ee->evas))
2610      evas_object_show(ee->prop.cursor.object);
2611
2612    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
2613 }
2614
2615 /*
2616  * @param ee
2617  * @param layer If < 3, @a ee will be put below all other windows.
2618  *              If > 5, @a ee will be "always-on-top"
2619  *              If = 4, @a ee will be put in the default layer.
2620  *              Acceptable values range from 1 to 255 (0 reserved for
2621  *              desktop windows)
2622  */
2623 static void
2624 _ecore_evas_x_layer_set(Ecore_Evas *ee, int layer)
2625 {
2626    if (ee->prop.layer == layer) return;
2627
2628    /* FIXME: Should this logic be here? */
2629    if (layer < 1)
2630      layer = 1;
2631    else if (layer > 255)
2632      layer = 255;
2633
2634    ee->prop.layer = layer;
2635    _ecore_evas_x_layer_update(ee);
2636 }
2637
2638 static void
2639 _ecore_evas_x_focus_set(Ecore_Evas *ee, int on __UNUSED__)
2640 {
2641    ecore_x_window_focus(ee->prop.window);
2642 }
2643
2644 static void
2645 _ecore_evas_x_iconified_set(Ecore_Evas *ee, int on)
2646 {
2647 //   if (((ee->prop.iconified) && (on)) ||
2648 //       ((!ee->prop.iconified) && (!on))) return;
2649    ee->prop.iconified = on;
2650    if (on)
2651      {
2652         ecore_x_icccm_hints_set(ee->prop.window,
2653                                 1 /* accepts_focus */,
2654                                 ECORE_X_WINDOW_STATE_HINT_ICONIC /* initial_state */,
2655                                 0 /* icon_pixmap */,
2656                                 0 /* icon_mask */,
2657                                 0 /* icon_window */,
2658                                 0 /* window_group */,
2659                                 0 /* is_urgent */);
2660         ecore_x_icccm_iconic_request_send(ee->prop.window, ee->engine.x.win_root);
2661      }
2662    else
2663      {
2664         ecore_x_icccm_hints_set(ee->prop.window,
2665                                 1 /* accepts_focus */,
2666                                 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2667                                 0 /* icon_pixmap */,
2668                                 0 /* icon_mask */,
2669                                 0 /* icon_window */,
2670                                 0 /* window_group */,
2671                                 0 /* is_urgent */);
2672         ecore_evas_show(ee);
2673      }
2674 }
2675
2676 static void
2677 _ecore_evas_x_borderless_set(Ecore_Evas *ee, int on)
2678 {
2679    if (((ee->prop.borderless) && (on)) ||
2680        ((!ee->prop.borderless) && (!on))) return;
2681    ee->prop.borderless = on;
2682    ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
2683 }
2684
2685 /* FIXME: This function changes the initial state of the ee
2686  * whilest the iconic function changes the current state! */
2687 static void
2688 _ecore_evas_x_withdrawn_set(Ecore_Evas *ee, int withdrawn)
2689 {
2690    Ecore_X_Window_State_Hint hint;
2691
2692    if ((ee->prop.withdrawn && withdrawn) ||
2693       (!ee->prop.withdrawn && !withdrawn)) return;
2694
2695    ee->prop.withdrawn = withdrawn;
2696    if (withdrawn)
2697      hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
2698    else
2699      hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
2700
2701    ecore_x_icccm_hints_set(ee->prop.window,
2702                            1 /* accepts_focus */,
2703                            hint /* initial_state */,
2704                            0 /* icon_pixmap */,
2705                            0 /* icon_mask */,
2706                            0 /* icon_window */,
2707                            0 /* window_group */,
2708                            0 /* is_urgent */);
2709 }
2710
2711 static void
2712 _ecore_evas_x_sticky_set(Ecore_Evas *ee, int sticky)
2713 {
2714    if ((ee->prop.sticky && sticky) ||
2715       (!ee->prop.sticky && !sticky)) return;
2716
2717    /* We dont want to set prop.sticky here as it will cause
2718     * the sticky callback not to get called. Its set on the
2719     * property change event.
2720     * ee->prop.sticky = sticky;
2721     */
2722    ee->engine.x.state.sticky = sticky;
2723    if (ee->should_be_visible)
2724      ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root,
2725                                       ECORE_X_WINDOW_STATE_STICKY, -1, sticky);
2726    else
2727      _ecore_evas_x_state_update(ee);
2728 }
2729
2730 static void
2731 _ecore_evas_x_ignore_events_set(Ecore_Evas *ee, int ignore)
2732 {
2733    if ((ee->ignore_events && ignore) ||
2734        (!ee->ignore_events && !ignore)) return;
2735
2736    if (ignore)
2737      {
2738         ee->ignore_events = 1;
2739         if (ee->prop.window)
2740           ecore_x_window_ignore_set(ee->prop.window, 1);
2741      }
2742    else
2743      {
2744         ee->ignore_events = 0;
2745         if (ee->prop.window)
2746           ecore_x_window_ignore_set(ee->prop.window, 0);
2747      }
2748 }
2749
2750 /*
2751 static void
2752 _ecore_evas_x_reinit_win(Ecore_Evas *ee)
2753 {
2754    if (!strcmp(ee->driver, "software_x11"))
2755      {
2756 #ifdef BUILD_ECORE_EVAS_X11
2757         Evas_Engine_Info_Software_X11 *einfo;
2758
2759         einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
2760         if (einfo)
2761           {
2762              einfo->info.drawable = ee->prop.window;
2763              evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
2764           }
2765 #endif
2766      }
2767    else if (!strcmp(ee->driver, "xrender_x11"))
2768      {
2769 #ifdef BUILD_ECORE_EVAS_XRENDER_X11
2770         Evas_Engine_Info_XRender_X11 *einfo;
2771
2772         einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
2773         if (einfo)
2774           {
2775              einfo->info.drawable = ee->prop.window;
2776              evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
2777           }
2778 #endif
2779      }
2780    else if (!strcmp(ee->driver, "opengl_x11"))
2781      {
2782 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
2783         Evas_Engine_Info_GL_X11 *einfo;
2784
2785         einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
2786         if (einfo)
2787           {
2788              einfo->info.drawable = ee->prop.window;
2789              evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
2790           }
2791 #endif
2792      }
2793 }
2794 */
2795
2796 static void
2797 _ecore_evas_x_override_set(Ecore_Evas *ee, int on)
2798 {
2799    if (((ee->prop.override) && (on)) ||
2800        ((!ee->prop.override) && (!on))) return;
2801    ecore_x_window_hide(ee->prop.window);
2802    ecore_x_window_override_set(ee->prop.window, on);
2803    if (ee->visible) ecore_x_window_show(ee->prop.window);
2804    if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
2805    ee->prop.override = on;
2806 }
2807
2808 static void
2809 _ecore_evas_x_fullscreen_set(Ecore_Evas *ee, int on)
2810 {
2811    if ((ee->prop.fullscreen && on) ||
2812       (!ee->prop.fullscreen && !on)) return;
2813
2814    /* FIXME: Detect if WM is EWMH compliant and handle properly if not,
2815     * i.e. reposition, resize, and change borderless hint */
2816    ee->engine.x.state.fullscreen = on;
2817    if (ee->should_be_visible)
2818      ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root,
2819                                       ECORE_X_WINDOW_STATE_FULLSCREEN, -1, on);
2820    else
2821      _ecore_evas_x_state_update(ee);
2822 }
2823
2824 static void
2825 _ecore_evas_x_avoid_damage_set(Ecore_Evas *ee, int on)
2826 {
2827    if (ee->prop.avoid_damage == on) return;
2828    if (!strcmp(ee->driver, "opengl_x11")) return;
2829    if (!strcmp(ee->driver, "xrender_x11")) return;
2830
2831    if (!strcmp(ee->driver, "software_x11"))
2832      {
2833 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
2834         Evas_Engine_Info_Software_X11 *einfo;
2835
2836         ee->prop.avoid_damage = on;
2837         einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
2838         if (einfo)
2839           {
2840              if (ee->prop.avoid_damage)
2841                {
2842                   ee->engine.x.pmap = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, einfo->info.depth);
2843                   ee->engine.x.gc = ecore_x_gc_new(ee->engine.x.pmap, 0, NULL);
2844                   einfo->info.drawable = ee->engine.x.pmap;
2845                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2846                     {
2847                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2848                     }
2849                   if ((ee->rotation == 90) || (ee->rotation == 270))
2850                     evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
2851                   else
2852                     evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
2853                   if (ee->prop.avoid_damage == ECORE_EVAS_AVOID_DAMAGE_BUILT_IN)
2854                     {
2855                        ee->engine.x.using_bg_pixmap = 1;
2856                        ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2857                        ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
2858                     }
2859                   if (ee->engine.x.direct_resize)
2860                     {
2861                        /* Turn this off for now
2862                           ee->engine.x.using_bg_pixmap = 1;
2863                           ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2864                        */
2865                     }
2866                }
2867              else
2868                {
2869                   if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap);
2870                   if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc);
2871                   if (ee->engine.x.using_bg_pixmap)
2872                     {
2873                        ecore_x_window_pixmap_set(ee->prop.window, 0);
2874                        ee->engine.x.using_bg_pixmap = 0;
2875                        ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
2876                     }
2877                   ee->engine.x.pmap = 0;
2878                   ee->engine.x.gc = 0;
2879                   einfo->info.drawable = ee->prop.window;
2880                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2881                     {
2882                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2883                     }
2884                }
2885           }
2886 #endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
2887      }
2888    else if (!strcmp(ee->driver, "software_16_x11"))
2889      {
2890 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
2891         Evas_Engine_Info_Software_16_X11 *einfo;
2892         ee->prop.avoid_damage = on;
2893
2894         einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
2895         if (einfo)
2896           {
2897              if (ee->prop.avoid_damage)
2898                {
2899                   ee->engine.x.pmap = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 16);
2900                   ee->engine.x.gc = ecore_x_gc_new(ee->engine.x.pmap, 0, NULL);
2901                   einfo->info.drawable = ee->engine.x.pmap;
2902                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2903                     {
2904                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2905                     }
2906                   if ((ee->rotation == 90) || (ee->rotation == 270))
2907                     evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
2908                   else
2909                     evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
2910                   if (ee->engine.x.direct_resize)
2911                     {
2912                        /* Turn this off for now
2913                           ee->engine.x.using_bg_pixmap = 1;
2914                           ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2915                        */
2916                     }
2917                }
2918              else
2919                {
2920                   if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap);
2921                   if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc);
2922                   if (ee->engine.x.using_bg_pixmap)
2923                     {
2924                        ecore_x_window_pixmap_set(ee->prop.window, 0);
2925                        ee->engine.x.using_bg_pixmap = 0;
2926                     }
2927                   ee->engine.x.pmap = 0;
2928                   ee->engine.x.gc = 0;
2929                   einfo->info.drawable = ee->prop.window;
2930                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2931                     {
2932                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2933                     }
2934                }
2935           }
2936 #endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
2937      }
2938    else if (!strcmp(ee->driver, "software_8_x11"))
2939      {
2940 #if BUILD_ECORE_EVAS_SOFTWARE_8_X11
2941         Evas_Engine_Info_Software_8_X11 *einfo;
2942
2943         ee->prop.avoid_damage = on;
2944         einfo = (Evas_Engine_Info_Software_8_X11 *)evas_engine_info_get(ee->evas);
2945         if (einfo)
2946           {
2947              if (ee->prop.avoid_damage)
2948                {
2949                   ee->engine.x.pmap = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, einfo->info.depth);
2950                   ee->engine.x.gc = ecore_x_gc_new(ee->engine.x.pmap, 0, NULL);
2951                   einfo->info.drawable = ee->engine.x.pmap;
2952                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2953                     {
2954                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2955                     }
2956                   if ((ee->rotation == 90) || (ee->rotation == 270))
2957                     evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
2958                   else
2959                     evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
2960                   if (ee->prop.avoid_damage == ECORE_EVAS_AVOID_DAMAGE_BUILT_IN)
2961                     {
2962                        ee->engine.x.using_bg_pixmap = 1;
2963                        ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2964                        ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
2965                     }
2966                   if (ee->engine.x.direct_resize)
2967                     {
2968                        /* Turn this off for now
2969                           ee->engine.x.using_bg_pixmap = 1;
2970                           ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2971                        */
2972                     }
2973                }
2974              else
2975                {
2976                   if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap);
2977                   if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc);
2978                   if (ee->engine.x.using_bg_pixmap)
2979                     {
2980                        ecore_x_window_pixmap_set(ee->prop.window, 0);
2981                        ee->engine.x.using_bg_pixmap = 0;
2982                        ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
2983                     }
2984                   ee->engine.x.pmap = 0;
2985                   ee->engine.x.gc = 0;
2986                   einfo->info.drawable = ee->prop.window;
2987                   if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
2988                     {
2989                        ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
2990                     }
2991                }
2992           }
2993 #endif /* BUILD_ECORE_EVAS_SOFTWARE_8_X11 */
2994      }
2995 }
2996
2997 static void
2998 _ecore_evas_x_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h)
2999 {
3000    if (x) *x = 0;
3001    if (y) *y = 0;
3002    ecore_x_screen_size_get(ecore_x_default_screen_get(), w, h);
3003 }
3004
3005 int
3006 _ecore_evas_x_shutdown(void)
3007 {
3008    _ecore_evas_init_count--;
3009    if (_ecore_evas_init_count == 0)
3010      {
3011         unsigned int i;
3012
3013         for (i = 0; i < sizeof(ecore_evas_event_handlers) / sizeof(Ecore_Event_Handler*); i++)
3014           {
3015              if (ecore_evas_event_handlers[i])
3016                ecore_event_handler_del(ecore_evas_event_handlers[i]);
3017           }
3018         ecore_event_evas_shutdown();
3019      }
3020    if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
3021    return _ecore_evas_init_count;
3022 }
3023
3024 static Ecore_Evas_Engine_Func _ecore_x_engine_func =
3025 {
3026    _ecore_evas_x_free,
3027      NULL,
3028      NULL,
3029      NULL,
3030      NULL,
3031      _ecore_evas_x_callback_delete_request_set,
3032      NULL,
3033      NULL,
3034      NULL,
3035      NULL,
3036      NULL,
3037      NULL,
3038      NULL,
3039      NULL,
3040      NULL,
3041      _ecore_evas_x_move,
3042      _ecore_evas_x_managed_move,
3043      _ecore_evas_x_resize,
3044      _ecore_evas_x_move_resize,
3045      _ecore_evas_x_rotation_set,
3046      _ecore_evas_x_shaped_set,
3047      _ecore_evas_x_show,
3048      _ecore_evas_x_hide,
3049      _ecore_evas_x_raise,
3050      _ecore_evas_x_lower,
3051      _ecore_evas_x_activate,
3052      _ecore_evas_x_title_set,
3053      _ecore_evas_x_name_class_set,
3054      _ecore_evas_x_size_min_set,
3055      _ecore_evas_x_size_max_set,
3056      _ecore_evas_x_size_base_set,
3057      _ecore_evas_x_size_step_set,
3058      _ecore_evas_x_object_cursor_set,
3059      _ecore_evas_x_layer_set,
3060      _ecore_evas_x_focus_set,
3061      _ecore_evas_x_iconified_set,
3062      _ecore_evas_x_borderless_set,
3063      _ecore_evas_x_override_set,
3064      NULL,
3065      _ecore_evas_x_fullscreen_set,
3066      _ecore_evas_x_avoid_damage_set,
3067      _ecore_evas_x_withdrawn_set,
3068      _ecore_evas_x_sticky_set,
3069      _ecore_evas_x_ignore_events_set,
3070      _ecore_evas_x_alpha_set,
3071      _ecore_evas_x_transparent_set,
3072
3073      NULL, // render
3074      _ecore_evas_x_screen_geometry_get
3075 };
3076 #endif /* BUILD_ECORE_EVAS_X11 */
3077
3078 /*
3079  * FIXME: there are some round trips. Especially, we can split
3080  * ecore_x_init in 2 functions and suppress some round trips.
3081  */
3082
3083 #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)
3084 static void
3085 _ecore_evas_x_flush_pre(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__)
3086 {
3087    Ecore_Evas *ee = data;
3088
3089    if (ee->no_comp_sync) return;
3090    if (!_ecore_evas_app_comp_sync) return;
3091    if (ee->engine.x.sync_counter)
3092      {
3093         if (ee->engine.x.sync_began)
3094           {
3095              ee->engine.x.sync_val++;
3096              if (!ee->engine.x.sync_cancel)
3097                {
3098                   if (!ee->semi_sync)
3099                      ecore_x_sync_counter_val_wait(ee->engine.x.sync_counter,
3100                                                    ee->engine.x.sync_val);
3101                }
3102           }
3103      }
3104 }
3105
3106 static void
3107 _ecore_evas_x_flush_post(void *data, Evas *e __UNUSED__, void *event_info __UNUSED__)
3108 {
3109    Ecore_Evas *ee = data;
3110
3111    if ((!ee->no_comp_sync) &&
3112        (_ecore_evas_app_comp_sync) &&
3113        (!ee->gl_sync_draw_done)) // added by gl77.lee
3114      {
3115         if (ee->engine.x.sync_counter)
3116           {
3117              if (ee->engine.x.sync_began)
3118                {
3119                   if (!ee->engine.x.sync_cancel)
3120                     {
3121                        ecore_x_e_comp_sync_draw_size_done_send
3122                           (ee->engine.x.win_root, ee->prop.window, ee->w, ee->h);
3123                     }
3124                }
3125           }
3126      }
3127    if (ee->engine.x.netwm_sync_set)
3128      {
3129         ecore_x_sync_counter_2_set(ee->engine.x.netwm_sync_counter,
3130                                    ee->engine.x.netwm_sync_val_hi,
3131                                    ee->engine.x.netwm_sync_val_lo);
3132         ee->engine.x.netwm_sync_set = 0;
3133      }
3134 }
3135 #endif
3136
3137 /**
3138  * To be documented.
3139  *
3140  * FIXME: To be fixed.
3141  */
3142 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
3143 EAPI Ecore_Evas *
3144 ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent,
3145                             int x, int y, int w, int h)
3146 {
3147    Evas_Engine_Info_Software_X11 *einfo;
3148    Ecore_Evas *ee;
3149    int argb = 0;
3150    int rmethod;
3151    static int redraw_debug = -1;
3152
3153    rmethod = evas_render_method_lookup("software_x11");
3154    if (!rmethod) return NULL;
3155    if (!ecore_x_init(disp_name)) return NULL;
3156    ee = calloc(1, sizeof(Ecore_Evas));
3157    if (!ee) return NULL;
3158
3159    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
3160
3161    _ecore_evas_x_init();
3162
3163    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
3164
3165    ee->driver = "software_x11";
3166    if (disp_name) ee->name = strdup(disp_name);
3167
3168    if (w < 1) w = 1;
3169    if (h < 1) h = 1;
3170    ee->x = x;
3171    ee->y = y;
3172    ee->w = w;
3173    ee->h = h;
3174    ee->req.x = ee->x;
3175    ee->req.y = ee->y;
3176    ee->req.w = ee->w;
3177    ee->req.h = ee->h;
3178
3179    ee->prop.max.w = 32767;
3180    ee->prop.max.h = 32767;
3181    ee->prop.layer = 4;
3182    ee->prop.request_pos = 0;
3183    ee->prop.sticky = 0;
3184    ee->engine.x.state.sticky = 0;
3185
3186    /* init evas here */
3187    ee->evas = evas_new();
3188    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
3189    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
3190    evas_data_attach_set(ee->evas, ee);
3191    evas_output_method_set(ee->evas, rmethod);
3192    evas_output_size_set(ee->evas, w, h);
3193    evas_output_viewport_set(ee->evas, 0, 0, w, h);
3194
3195    ee->engine.x.win_root = parent;
3196    ee->engine.x.screen_num = 0;
3197
3198    if (parent != 0)
3199      {
3200         ee->engine.x.screen_num = 1; /* FIXME: get real scren # */
3201        /* FIXME: round trip in ecore_x_window_argb_get */
3202         if (ecore_x_window_argb_get(parent))
3203           {
3204              ee->prop.window = ecore_x_window_argb_new(parent, x, y, w, h);
3205              argb = 1;
3206           }
3207         else
3208           ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
3209      }
3210    else
3211      ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
3212    if (getenv("DESKTOP_STARTUP_ID"))
3213      {
3214         ecore_x_netwm_startup_id_set(ee->prop.window,
3215                                      getenv("DESKTOP_STARTUP_ID"));
3216         /* NB: on linux this may simply empty the env as opposed to completely
3217          * unset it to being empty - unsure as solartis libc crashes looking
3218          * for the '=' char */
3219 //        putenv((char*)"DESKTOP_STARTUP_ID=");
3220      }
3221    einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
3222    if (einfo)
3223      {
3224 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
3225         xcb_screen_iterator_t iter;
3226         xcb_screen_t         *screen;
3227 # else
3228         int screen;
3229 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
3230
3231         /* FIXME: this is inefficient as its a round trip */
3232 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
3233         screen = ecore_x_default_screen_get();
3234         iter = xcb_setup_roots_iterator (xcb_get_setup (ecore_x_connection_get()));
3235         if (iter.rem > 1)
3236           {
3237              xcb_get_geometry_cookie_t cookie;
3238              xcb_get_geometry_reply_t *reply;
3239              Ecore_X_Window           *roots;
3240              int                       num;
3241              uint8_t                   i;
3242
3243              num = 0;
3244              cookie = xcb_get_geometry_unchecked(ecore_x_connection_get(), parent);
3245              roots = ecore_x_window_root_list(&num);
3246              if (roots)
3247                {
3248                   reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
3249
3250                   if (reply)
3251                     {
3252                        for (i = 0; i < num; xcb_screen_next (&iter), i++)
3253                          {
3254                             if (reply->root == roots[i])
3255                               {
3256                                  screen = iter.data;
3257                                  break;
3258                               }
3259                          }
3260                        free(reply);
3261                     }
3262                   free(roots);
3263                }
3264              else
3265                {
3266                   reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
3267                   if (reply) free(reply);
3268                }
3269           }
3270 # else
3271         screen = DefaultScreen(ecore_x_display_get());
3272         if (ScreenCount(ecore_x_display_get()) > 1)
3273           {
3274              Ecore_X_Window *roots;
3275              int num, i;
3276
3277              num = 0;
3278              roots = ecore_x_window_root_list(&num);
3279              if (roots)
3280                {
3281                   XWindowAttributes at;
3282
3283                   if (XGetWindowAttributes(ecore_x_display_get(),
3284                                            parent, &at))
3285                     {
3286                        for (i = 0; i < num; i++)
3287                          {
3288                             if (at.root == roots[i])
3289                               {
3290                                  screen = i;
3291                                  break;
3292                               }
3293                          }
3294                     }
3295                   free(roots);
3296                }
3297           }
3298 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
3299
3300         if (redraw_debug < 0)
3301           {
3302              if (getenv("REDRAW_DEBUG"))
3303                redraw_debug = atoi(getenv("REDRAW_DEBUG"));
3304              else
3305                redraw_debug = 0;
3306           }
3307 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
3308         einfo->info.backend = EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB;
3309         einfo->info.connection = ecore_x_connection_get();
3310         einfo->info.screen = screen;
3311 # else
3312         einfo->info.backend = EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB;
3313         einfo->info.connection = ecore_x_display_get();
3314         einfo->info.screen = NULL;
3315 #ifdef EVAS_FRAME_QUEUING
3316         {
3317            char    *render_mode;
3318            render_mode = getenv("EVAS_RENDER_MODE");
3319            if (render_mode && !strcmp(render_mode, "non-blocking"))
3320              {
3321                 einfo->render_mode = EVAS_RENDER_MODE_NONBLOCKING;
3322              }
3323         }
3324 #endif
3325
3326 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
3327         einfo->info.drawable = ee->prop.window;
3328         if (argb)
3329           {
3330         /* FIXME: round trip */
3331 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
3332              xcb_get_geometry_cookie_t          cookie_geom;
3333              xcb_get_window_attributes_cookie_t cookie_attr;
3334              xcb_get_geometry_reply_t          *reply_geom;
3335              xcb_get_window_attributes_reply_t *reply_attr;
3336
3337              cookie_geom = xcb_get_geometry_unchecked(ecore_x_connection_get(), ee->prop.window);
3338              cookie_attr = xcb_get_window_attributes_unchecked(ecore_x_connection_get(), ee->prop.window);
3339
3340              reply_geom = xcb_get_geometry_reply(ecore_x_connection_get(), cookie_geom, NULL);
3341              reply_attr = xcb_get_window_attributes_reply(ecore_x_connection_get(), cookie_attr, NULL);
3342              if (reply_attr && reply_geom)
3343                {
3344                   einfo->info.visual   = xcb_visualtype_get(ecore_x_default_screen_get(), reply_attr->visual);
3345                   einfo->info.colormap = reply_attr->colormap;
3346                   einfo->info.depth    = reply_geom->depth;
3347                   einfo->info.destination_alpha = 1;
3348                   free(reply_geom);
3349                   free(reply_attr);
3350                }
3351 # else
3352              XWindowAttributes at;
3353
3354              if (XGetWindowAttributes(ecore_x_display_get(), ee->prop.window,
3355                                       &at))
3356                {
3357                   einfo->info.visual   = at.visual;
3358                   einfo->info.colormap = at.colormap;
3359                   einfo->info.depth    = at.depth;
3360                   einfo->info.destination_alpha = 1;
3361                }
3362 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
3363           }
3364         else
3365           {
3366 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
3367              xcb_screen_t *screen;
3368
3369              screen = ecore_x_default_screen_get();
3370              einfo->info.visual   = xcb_visualtype_get(screen, screen->root_visual);
3371              einfo->info.colormap = screen->default_colormap;
3372              einfo->info.depth    = screen->root_depth;
3373 #else
3374              einfo->info.visual   = DefaultVisual(ecore_x_display_get(), screen);
3375              einfo->info.colormap = DefaultColormap(ecore_x_display_get(), screen);
3376              einfo->info.depth    = DefaultDepth(ecore_x_display_get(), screen);
3377 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
3378              einfo->info.destination_alpha = 0;
3379           }
3380         einfo->info.rotation = 0;
3381         einfo->info.debug    = redraw_debug;
3382         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
3383           {
3384              ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
3385              ecore_evas_free(ee);
3386              return NULL;
3387           }
3388      }
3389
3390    ecore_x_icccm_hints_set(ee->prop.window,
3391                            1 /* accepts_focus */,
3392                            ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
3393                            0 /* icon_pixmap */,
3394                            0 /* icon_mask */,
3395                            0 /* icon_window */,
3396                            0 /* window_group */,
3397                            0 /* is_urgent */);
3398    _ecore_evas_x_group_leader_set(ee);
3399    ecore_x_window_defaults_set(ee->prop.window);
3400    _ecore_evas_x_protocols_set(ee);
3401    _ecore_evas_x_sync_set(ee);
3402
3403    ee->engine.func->fn_render = _ecore_evas_x_render;
3404    _ecore_evas_register(ee);
3405    ecore_x_input_multi_select(ee->prop.window);
3406    ecore_event_window_register(ee->prop.window, ee, ee->evas,
3407                                (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
3408                                (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
3409                                (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
3410                                (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
3411    return ee;
3412 }
3413 #else
3414 EAPI Ecore_Evas *
3415 ecore_evas_software_x11_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
3416                             int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
3417 {
3418    return NULL;
3419 }
3420 #endif
3421
3422 /**
3423  * To be documented.
3424  *
3425  * FIXME: To be fixed.
3426  */
3427 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
3428 EAPI Ecore_X_Window
3429 ecore_evas_software_x11_window_get(const Ecore_Evas *ee)
3430 {
3431    return (Ecore_X_Window) ecore_evas_window_get(ee);
3432 }
3433 #else
3434 EAPI Ecore_X_Window
3435 ecore_evas_software_x11_window_get(const Ecore_Evas *ee __UNUSED__)
3436 {
3437    return 0;
3438 }
3439 #endif
3440
3441 /**
3442  * To be documented.
3443  *
3444  * FIXME: To be fixed.
3445  */
3446 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
3447 EAPI void
3448 ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee, Eina_Bool on)
3449 {
3450    ee->engine.x.direct_resize = on;
3451    if (ee->prop.avoid_damage)
3452      {
3453         if (ee->engine.x.direct_resize)
3454           {
3455 /* turn this off for now
3456              ee->engine.x.using_bg_pixmap = 1;
3457              ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
3458  */
3459           }
3460         else
3461           {
3462 /* turn this off too- bg pixmap is controlled by avoid damage directly
3463              ee->engine.x.using_bg_pixmap = 0;
3464              ecore_x_window_pixmap_set(ee->prop.window, 0);
3465              ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
3466  */
3467           }
3468      }
3469 }
3470 #else
3471 EAPI void
3472 ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee __UNUSED__, Eina_Bool on __UNUSED__)
3473 {
3474 }
3475 #endif
3476
3477 /**
3478  * To be documented.
3479  *
3480  * FIXME: To be fixed.
3481  */
3482 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
3483 EAPI Eina_Bool
3484 ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee)
3485 {
3486    return ee->engine.x.direct_resize;
3487 }
3488 #else
3489 EAPI Eina_Bool
3490 ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
3491 {
3492    return 0;
3493 }
3494 #endif
3495
3496 /**
3497  * To be documented.
3498  *
3499  * FIXME: To be fixed.
3500  */
3501 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
3502 EAPI void
3503 ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
3504 {
3505    Ecore_X_Window *winp;
3506
3507    winp = malloc(sizeof(Ecore_X_Window));
3508    if (winp)
3509      {
3510         *winp = win;
3511         ee->engine.x.win_extra = eina_list_append(ee->engine.x.win_extra, winp);
3512         ecore_x_input_multi_select(win);
3513         ecore_event_window_register(win, ee, ee->evas,
3514                                     (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
3515                                     (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
3516                                     (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
3517                                     (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
3518      }
3519 }
3520 #else
3521 EAPI void
3522 ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
3523 {
3524 }
3525 #endif
3526
3527 /**
3528  * To be documented.
3529  *
3530  * FIXME: To be fixed.
3531  */
3532 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
3533 EAPI Ecore_Evas *
3534 ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent,
3535                       int x, int y, int w, int h)
3536 {
3537    return ecore_evas_gl_x11_options_new(disp_name, parent, x, y, w, h, NULL);
3538 }
3539 EAPI Ecore_Evas *
3540 ecore_evas_gl_x11_options_new(const char *disp_name, Ecore_X_Window parent,
3541                               int x, int y, int w, int h, const int *opt)
3542 {
3543 # ifdef HAVE_ECORE_X_XCB
3544    Ecore_Evas *ee = NULL;
3545 # else
3546    Ecore_Evas *ee;
3547    int rmethod;
3548
3549    rmethod = evas_render_method_lookup("gl_x11");
3550    if (!rmethod) return NULL;
3551    if (!ecore_x_init(disp_name)) return NULL;
3552    ee = calloc(1, sizeof(Ecore_Evas));
3553    if (!ee) return NULL;
3554
3555    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
3556
3557    ee->gl_sync_draw_done = -1; // added by gl77.lee
3558
3559    _ecore_evas_x_init();
3560
3561    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
3562
3563    ee->driver = "opengl_x11";
3564    ee->semi_sync = 0; // gl engine doesn't need to sync - its whole swaps
3565 //   ee->no_comp_sync = 1; // gl engine doesn't need to sync - its whole swaps
3566    if (disp_name) ee->name = strdup(disp_name);
3567
3568    if (w < 1) w = 1;
3569    if (h < 1) h = 1;
3570    ee->x = x;
3571    ee->y = y;
3572    ee->w = w;
3573    ee->h = h;
3574    ee->req.x = ee->x;
3575    ee->req.y = ee->y;
3576    ee->req.w = ee->w;
3577    ee->req.h = ee->h;
3578
3579    ee->prop.max.w = 32767;
3580    ee->prop.max.h = 32767;
3581    ee->prop.layer = 4;
3582    ee->prop.request_pos = 0;
3583    ee->prop.sticky = 0;
3584    ee->engine.x.state.sticky = 0;
3585
3586    /* init evas here */
3587    ee->evas = evas_new();
3588    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
3589    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
3590    evas_data_attach_set(ee->evas, ee);
3591    evas_output_method_set(ee->evas, rmethod);
3592    evas_output_size_set(ee->evas, w, h);
3593    evas_output_viewport_set(ee->evas, 0, 0, w, h);
3594
3595    if (parent == 0) parent = DefaultRootWindow(ecore_x_display_get());
3596    ee->engine.x.win_root = parent;
3597
3598    if (ee->engine.x.win_root != 0)
3599      {
3600         ee->engine.x.screen_num = 1; /* FIXME: get real scren # */
3601        /* FIXME: round trip in ecore_x_window_argb_get */
3602         if (ecore_x_window_argb_get(ee->engine.x.win_root))
3603           {
3604              ee->prop.window = _ecore_evas_x_gl_window_new
3605                (ee, ee->engine.x.win_root, x, y, w, h, 0, 1, opt);
3606           }
3607         else
3608           ee->prop.window = _ecore_evas_x_gl_window_new
3609           (ee, ee->engine.x.win_root, x, y, w, h, 0, 0, opt);
3610      }
3611    else
3612      ee->prop.window = _ecore_evas_x_gl_window_new
3613      (ee, ee->engine.x.win_root, x, y, w, h, 0, 0, opt);
3614    if (!ee->prop.window)
3615      {
3616         ecore_evas_free(ee);
3617         return NULL;
3618      }
3619    if (getenv("DESKTOP_STARTUP_ID"))
3620      {
3621         ecore_x_netwm_startup_id_set(ee->prop.window,
3622                                      getenv("DESKTOP_STARTUP_ID"));
3623         /* NB: on linux this may simply empty the env as opposed to completely
3624          * unset it to being empty - unsure as solartis libc crashes looking
3625          * for the '=' char */
3626 //        putenv((char*)"DESKTOP_STARTUP_ID=");
3627      }
3628
3629    ecore_x_icccm_hints_set(ee->prop.window,
3630                            1 /* accepts_focus */,
3631                            ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
3632                            0 /* icon_pixmap */,
3633                            0 /* icon_mask */,
3634                            0 /* icon_window */,
3635                            0 /* window_group */,
3636                            0 /* is_urgent */);
3637    _ecore_evas_x_group_leader_set(ee);
3638    ecore_x_window_defaults_set(ee->prop.window);
3639    _ecore_evas_x_protocols_set(ee);
3640    _ecore_evas_x_sync_set(ee);
3641
3642    ee->engine.func->fn_render = _ecore_evas_x_render;
3643    _ecore_evas_register(ee);
3644    ecore_x_input_multi_select(ee->prop.window);
3645    ecore_event_window_register(ee->prop.window, ee, ee->evas,
3646                                (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
3647                                (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
3648                                (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
3649                                (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
3650 # endif /* HAVE_ECORE_X_XCB */
3651
3652    return ee;
3653 }
3654 #else
3655 EAPI Ecore_Evas *
3656 ecore_evas_gl_x11_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
3657                       int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
3658 {
3659    return NULL;
3660 }
3661 EAPI Ecore_Evas *
3662 ecore_evas_gl_x11_options_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
3663                               int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__, const int *opt __UNUSED__)
3664 {
3665    return NULL;
3666 }
3667 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3668
3669 /**
3670  * To be documented.
3671  *
3672  * FIXME: To be fixed.
3673  */
3674 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
3675 EAPI Ecore_X_Window
3676 ecore_evas_gl_x11_window_get(const Ecore_Evas *ee)
3677 {
3678    return (Ecore_X_Window) ecore_evas_window_get(ee);
3679 }
3680 #else
3681 EAPI Ecore_X_Window
3682 ecore_evas_gl_x11_window_get(const Ecore_Evas *ee __UNUSED__)
3683 {
3684    return 0;
3685 }
3686 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3687
3688 /**
3689  * To be documented.
3690  *
3691  * FIXME: To be fixed.
3692  */
3693 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
3694 EAPI void
3695 ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee, Eina_Bool on)
3696 {
3697    ee->engine.x.direct_resize = on;
3698 }
3699 #else
3700 EAPI void
3701 ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee __UNUSED__, Eina_Bool on __UNUSED__)
3702 {
3703 }
3704 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3705
3706 /**
3707  * To be documented.
3708  *
3709  * FIXME: To be fixed.
3710  */
3711 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
3712 EAPI Eina_Bool
3713 ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee)
3714 {
3715    return ee->engine.x.direct_resize;
3716 }
3717 #else
3718 EAPI Eina_Bool
3719 ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
3720 {
3721    return 0;
3722 }
3723 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3724
3725 /**
3726  * To be documented.
3727  *
3728  * FIXME: To be fixed.
3729  */
3730 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
3731 EAPI void
3732 ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
3733 {
3734    ecore_evas_software_x11_extra_event_window_add(ee, win);
3735 }
3736 #else
3737 EAPI void
3738 ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
3739 {
3740 }
3741 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3742
3743 /**
3744  * To be documented.
3745  *
3746  * FIXME: To be fixed.
3747  */
3748 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
3749 EAPI void
3750 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))
3751 {
3752    Evas_Engine_Info_GL_X11 *einfo;
3753
3754    if (!(!strcmp(ee->driver, "opengl_x11"))) return;
3755
3756    einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
3757    if (einfo)
3758      {
3759         einfo->callback.pre_swap = pre_cb;
3760         einfo->callback.pre_swap = post_cb;
3761         einfo->callback.data = data;
3762         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
3763           {
3764              ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
3765           }
3766      }
3767 }
3768 #else
3769 EAPI void
3770 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__)
3771 {
3772    return;
3773 }
3774 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
3775
3776 /**
3777  * To be documented.
3778  *
3779  * FIXME: To be fixed.
3780  */
3781 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
3782 EAPI Ecore_Evas *
3783 ecore_evas_xrender_x11_new(const char *disp_name, Ecore_X_Window parent,
3784                       int x, int y, int w, int h)
3785 {
3786    Evas_Engine_Info_XRender_X11 *einfo;
3787    Ecore_Evas *ee;
3788    int rmethod;
3789
3790    rmethod = evas_render_method_lookup("xrender_x11");
3791    if (!rmethod) return NULL;
3792    if (!ecore_x_init(disp_name)) return NULL;
3793    ee = calloc(1, sizeof(Ecore_Evas));
3794    if (!ee) return NULL;
3795
3796    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
3797
3798    _ecore_evas_x_init();
3799
3800    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
3801
3802    ee->driver = "xrender_x11";
3803    if (disp_name) ee->name = strdup(disp_name);
3804
3805    if (w < 1) w = 1;
3806    if (h < 1) h = 1;
3807    ee->x = x;
3808    ee->y = y;
3809    ee->w = w;
3810    ee->h = h;
3811    ee->req.x = ee->x;
3812    ee->req.y = ee->y;
3813    ee->req.w = ee->w;
3814    ee->req.h = ee->h;
3815
3816    ee->prop.max.w = 32767;
3817    ee->prop.max.h = 32767;
3818    ee->prop.layer = 4;
3819    ee->prop.request_pos = 0;
3820    ee->prop.sticky = 0;
3821    ee->engine.x.state.sticky = 0;
3822
3823    /* init evas here */
3824    ee->evas = evas_new();
3825    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
3826    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
3827    evas_data_attach_set(ee->evas, ee);
3828    evas_output_method_set(ee->evas, rmethod);
3829    evas_output_size_set(ee->evas, w, h);
3830    evas_output_viewport_set(ee->evas, 0, 0, w, h);
3831
3832    ee->engine.x.win_root = parent;
3833    ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
3834    if (getenv("DESKTOP_STARTUP_ID"))
3835      {
3836         ecore_x_netwm_startup_id_set(ee->prop.window,
3837                                      getenv("DESKTOP_STARTUP_ID"));
3838         /* NB: on linux this may simply empty the env as opposed to completely
3839          * unset it to being empty - unsure as solartis libc crashes looking
3840          * for the '=' char */
3841 //        putenv((char*)"DESKTOP_STARTUP_ID=");
3842      }
3843    einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
3844    if (einfo)
3845      {
3846 # ifdef BUILD_ECORE_EVAS_XRENDER_XCB
3847         xcb_screen_iterator_t iter;
3848         xcb_screen_t         *screen;
3849
3850         /* FIXME: this is inefficient as its a round trip */
3851         screen = ecore_x_default_screen_get();
3852         iter = xcb_setup_roots_iterator (xcb_get_setup (ecore_x_connection_get()));
3853         if (iter.rem > 1)
3854           {
3855              xcb_get_geometry_cookie_t cookie;
3856              xcb_get_geometry_reply_t *reply;
3857              Ecore_X_Window           *roots;
3858              int                       num;
3859              uint8_t                   i;
3860
3861              num = 0;
3862              cookie = xcb_get_geometry_unchecked(ecore_x_connection_get(), parent);
3863              roots = ecore_x_window_root_list(&num);
3864              if (roots)
3865                {
3866                   reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
3867
3868                   if (reply)
3869                     {
3870                        for (i = 0; i < num; xcb_screen_next (&iter), i++)
3871                          {
3872                             if (reply->root == roots[i])
3873                               {
3874                                  screen = iter.data;
3875                                  break;
3876                               }
3877                          }
3878                        free(reply);
3879                     }
3880                   free(roots);
3881                }
3882              else
3883                {
3884                   reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
3885                   if (reply) free(reply);
3886                }
3887           }
3888         einfo->info.backend = EVAS_ENGINE_INFO_XRENDER_BACKEND_XCB;
3889         einfo->info.connection = ecore_x_connection_get();
3890         einfo->info.screen = screen;
3891         einfo->info.visual = screen->root_visual;
3892 # elif BUILD_ECORE_EVAS_XRENDER_X11
3893         int screen;
3894
3895         /* FIXME: this is inefficient as its a round trip */
3896         screen = DefaultScreen(ecore_x_display_get());
3897         if (ScreenCount(ecore_x_display_get()) > 1)
3898           {
3899              Ecore_X_Window *roots;
3900              int num, i;
3901
3902              num = 0;
3903              roots = ecore_x_window_root_list(&num);
3904              if (roots)
3905                {
3906                   XWindowAttributes at;
3907
3908                   if (XGetWindowAttributes(ecore_x_display_get(),
3909                                            parent, &at))
3910                     {
3911                        for (i = 0; i < num; i++)
3912                          {
3913                             if (at.root == roots[i])
3914                               {
3915                                  screen = i;
3916                                  break;
3917                               }
3918                          }
3919                     }
3920                   free(roots);
3921                }
3922           }
3923         einfo->info.backend = EVAS_ENGINE_INFO_XRENDER_BACKEND_XLIB;
3924         einfo->info.connection = ecore_x_display_get();
3925         einfo->info.screen = NULL;
3926         einfo->info.visual = DefaultVisual(ecore_x_display_get(), screen);
3927 # endif /* BUILD_ECORE_EVAS_XRENDER_(XCB|X11) */
3928         einfo->info.drawable = ee->prop.window;
3929         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
3930           {
3931              ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
3932              ecore_evas_free(ee);
3933              return NULL;
3934           }
3935      }
3936
3937    ecore_x_icccm_hints_set(ee->prop.window,
3938                            1 /* accepts_focus */,
3939                            ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
3940                            0 /* icon_pixmap */,
3941                            0 /* icon_mask */,
3942                            0 /* icon_window */,
3943                            0 /* window_group */,
3944                            0 /* is_urgent */);
3945    _ecore_evas_x_group_leader_set(ee);
3946    ecore_x_window_defaults_set(ee->prop.window);
3947    _ecore_evas_x_protocols_set(ee);
3948    _ecore_evas_x_sync_set(ee);
3949
3950    ee->engine.func->fn_render = _ecore_evas_x_render;
3951    _ecore_evas_register(ee);
3952    ecore_x_input_multi_select(ee->prop.window);
3953    ecore_event_window_register(ee->prop.window, ee, ee->evas,
3954                                (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
3955                                (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
3956                                (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
3957                                (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
3958    return ee;
3959 }
3960 #else
3961 EAPI Ecore_Evas *
3962 ecore_evas_xrender_x11_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
3963                            int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
3964 {
3965    return NULL;
3966 }
3967 #endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
3968
3969 /**
3970  * To be documented.
3971  *
3972  * FIXME: To be fixed.
3973  */
3974 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
3975 EAPI Ecore_X_Window
3976 ecore_evas_xrender_x11_window_get(const Ecore_Evas *ee)
3977 {
3978    return (Ecore_X_Window) ecore_evas_window_get(ee);
3979 }
3980 #else
3981 EAPI Ecore_X_Window
3982 ecore_evas_xrender_x11_window_get(const Ecore_Evas *ee __UNUSED__)
3983 {
3984    return 0;
3985 }
3986 #endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
3987
3988 /**
3989  * To be documented.
3990  *
3991  * FIXME: To be fixed.
3992  */
3993 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
3994 EAPI void
3995 ecore_evas_xrender_x11_direct_resize_set(Ecore_Evas *ee, Eina_Bool on)
3996 {
3997    ee->engine.x.direct_resize = on;
3998 }
3999 #else
4000 EAPI void
4001 ecore_evas_xrender_x11_direct_resize_set(Ecore_Evas *ee __UNUSED__, Eina_Bool on __UNUSED__)
4002 {
4003 }
4004 #endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
4005
4006 /**
4007  * To be documented.
4008  *
4009  * FIXME: To be fixed.
4010  */
4011 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
4012 EAPI Eina_Bool
4013 ecore_evas_xrender_x11_direct_resize_get(const Ecore_Evas *ee)
4014 {
4015    return ee->engine.x.direct_resize;
4016 }
4017 #else
4018 EAPI Eina_Bool
4019 ecore_evas_xrender_x11_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
4020 {
4021    return 0;
4022 }
4023 #endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
4024
4025 /**
4026  * To be documented.
4027  *
4028  * FIXME: To be fixed.
4029  */
4030 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
4031 EAPI void
4032 ecore_evas_xrender_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
4033 {
4034    ecore_evas_software_x11_extra_event_window_add(ee, win);
4035 }
4036 #else
4037 EAPI void
4038 ecore_evas_xrender_x11_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
4039 {
4040 }
4041 #endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
4042
4043 /**
4044  * To be documented.
4045  *
4046  * FIXME: To be fixed.
4047  */
4048 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
4049 EAPI Ecore_Evas *
4050 ecore_evas_software_x11_16_new(const char *disp_name, Ecore_X_Window parent,
4051                                int x, int y, int w, int h)
4052 {
4053    Evas_Engine_Info_Software_16_X11 *einfo;
4054    Ecore_Evas *ee;
4055    int rmethod;
4056    static int redraw_debug = -1;
4057
4058    rmethod = evas_render_method_lookup("software_16_x11");
4059    if (!rmethod) return NULL;
4060    if (!ecore_x_init(disp_name)) return NULL;
4061    ee = calloc(1, sizeof(Ecore_Evas));
4062    if (!ee) return NULL;
4063
4064    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
4065
4066    _ecore_evas_x_init();
4067
4068    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
4069
4070    ee->driver = "software_16_x11";
4071    if (disp_name) ee->name = strdup(disp_name);
4072
4073    if (w < 1) w = 1;
4074    if (h < 1) h = 1;
4075    ee->x = x;
4076    ee->y = y;
4077    ee->w = w;
4078    ee->h = h;
4079    ee->req.x = ee->x;
4080    ee->req.y = ee->y;
4081    ee->req.w = ee->w;
4082    ee->req.h = ee->h;
4083
4084    ee->prop.max.w = 32767;
4085    ee->prop.max.h = 32767;
4086    ee->prop.layer = 4;
4087    ee->prop.request_pos = 0;
4088    ee->prop.sticky = 0;
4089    ee->engine.x.state.sticky = 0;
4090
4091    /* init evas here */
4092    ee->evas = evas_new();
4093    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
4094    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
4095    evas_data_attach_set(ee->evas, ee);
4096    evas_output_method_set(ee->evas, rmethod);
4097    evas_output_size_set(ee->evas, w, h);
4098    evas_output_viewport_set(ee->evas, 0, 0, w, h);
4099
4100    ee->engine.x.win_root = parent;
4101    if (parent != 0)
4102      {
4103        /* FIXME: round trip in ecore_x_window_argb_get */
4104         if (ecore_x_window_argb_get(parent))
4105           {
4106              ee->prop.window = ecore_x_window_argb_new(parent, x, y, w, h);
4107           }
4108         else
4109           ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
4110      }
4111    else
4112      ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
4113    if (getenv("DESKTOP_STARTUP_ID"))
4114      {
4115         ecore_x_netwm_startup_id_set(ee->prop.window,
4116                                      getenv("DESKTOP_STARTUP_ID"));
4117         /* NB: on linux this may simply empty the env as opposed to completely
4118          * unset it to being empty - unsure as solartis libc crashes looking
4119          * for the '=' char */
4120 //        putenv((char*)"DESKTOP_STARTUP_ID=");
4121      }
4122    einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
4123
4124    if (einfo)
4125      {
4126         if (ScreenCount(ecore_x_display_get()) > 1)
4127           {
4128              Ecore_X_Window *roots;
4129              int num, i;
4130
4131              num = 0;
4132              roots = ecore_x_window_root_list(&num);
4133              if (roots)
4134                {
4135                   XWindowAttributes at;
4136
4137                   if (XGetWindowAttributes(ecore_x_display_get(),
4138                                            parent, &at))
4139                     {
4140                        for (i = 0; i < num; i++)
4141                          {
4142                             if (at.root == roots[i])
4143                               break;
4144                          }
4145                     }
4146                   free(roots);
4147                }
4148           }
4149
4150         if (redraw_debug < 0)
4151           {
4152              if (getenv("REDRAW_DEBUG"))
4153                redraw_debug = atoi(getenv("REDRAW_DEBUG"));
4154              else
4155                redraw_debug = 0;
4156           }
4157         einfo->info.display  = ecore_x_display_get();
4158         einfo->info.drawable = ee->prop.window;
4159
4160         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
4161           {
4162              ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
4163              ecore_evas_free(ee);
4164              return NULL;
4165           }
4166      }
4167
4168    ecore_x_icccm_hints_set(ee->prop.window,
4169                            1 /* accepts_focus */,
4170                            ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
4171                            0 /* icon_pixmap */,
4172                            0 /* icon_mask */,
4173                            0 /* icon_window */,
4174                            0 /* window_group */,
4175                            0 /* is_urgent */);
4176    _ecore_evas_x_group_leader_set(ee);
4177    ecore_x_window_defaults_set(ee->prop.window);
4178    _ecore_evas_x_protocols_set(ee);
4179    _ecore_evas_x_sync_set(ee);
4180
4181    ee->engine.func->fn_render = _ecore_evas_x_render;
4182    _ecore_evas_register(ee);
4183    ecore_x_input_multi_select(ee->prop.window);
4184    ecore_event_window_register(ee->prop.window, ee, ee->evas,
4185                                (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
4186                                (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
4187                                (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
4188                                (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
4189    return ee;
4190 }
4191 #else
4192 EAPI Ecore_Evas *
4193 ecore_evas_software_x11_16_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
4194                                int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
4195 {
4196    return NULL;
4197 }
4198 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
4199
4200 /**
4201  * To be documented.
4202  *
4203  * FIXME: To be fixed.
4204  */
4205 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
4206 EAPI Ecore_X_Window
4207 ecore_evas_software_x11_16_window_get(const Ecore_Evas *ee)
4208 {
4209    return (Ecore_X_Window) ecore_evas_window_get(ee);
4210 }
4211 #else
4212 EAPI Ecore_X_Window
4213 ecore_evas_software_x11_16_window_get(const Ecore_Evas *ee __UNUSED__)
4214 {
4215    return 0;
4216 }
4217 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
4218
4219 /**
4220  * To be documented.
4221  *
4222  * FIXME: To be fixed.
4223  */
4224 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
4225 EAPI void
4226 ecore_evas_software_x11_16_direct_resize_set(Ecore_Evas *ee, Eina_Bool on)
4227 {
4228    ee->engine.x.direct_resize = on;
4229    if (ee->prop.avoid_damage)
4230      {
4231         if (ee->engine.x.direct_resize)
4232           {
4233 /* turn this off for now
4234              ee->engine.x.using_bg_pixmap = 1;
4235              ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
4236  */
4237           }
4238         else
4239           {
4240 /* turn this off too- bg pixmap is controlled by avoid damage directly
4241              ee->engine.x.using_bg_pixmap = 0;
4242              ecore_x_window_pixmap_set(ee->prop.window, 0);
4243              ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
4244  */
4245           }
4246      }
4247 }
4248 #else
4249 EAPI void
4250 ecore_evas_software_x11_16_direct_resize_set(Ecore_Evas *ee __UNUSED__, Eina_Bool on __UNUSED__)
4251 {
4252 }
4253 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
4254
4255 /**
4256  * To be documented.
4257  *
4258  * FIXME: To be fixed.
4259  */
4260 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
4261 EAPI Eina_Bool
4262 ecore_evas_software_x11_16_direct_resize_get(const Ecore_Evas *ee)
4263 {
4264    return ee->engine.x.direct_resize;
4265 }
4266 #else
4267 EAPI Eina_Bool
4268 ecore_evas_software_x11_16_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
4269 {
4270    return 0;
4271 }
4272 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
4273
4274 /**
4275  * To be documented.
4276  *
4277  * FIXME: To be fixed.
4278  */
4279 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
4280 EAPI void
4281 ecore_evas_software_x11_16_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
4282 {
4283    Ecore_X_Window *winp;
4284
4285    winp = malloc(sizeof(Ecore_X_Window));
4286    if (winp)
4287      {
4288         *winp = win;
4289         ee->engine.x.win_extra = eina_list_append(ee->engine.x.win_extra, winp);
4290         ecore_x_input_multi_select(win);
4291         ecore_event_window_register(win, ee, ee->evas,
4292                                     (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
4293                                     (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
4294                                     (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
4295                                     (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
4296      }
4297 }
4298 #else
4299 EAPI void
4300 ecore_evas_software_x11_16_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
4301 {
4302 }
4303 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
4304
4305
4306 /**
4307  * To be documented.
4308  *
4309  * FIXME: To be fixed.
4310  */
4311 EAPI Ecore_Evas *
4312 ecore_evas_software_x11_8_new(const char *disp_name, Ecore_X_Window parent,
4313                               int x, int y, int w, int h)
4314 {
4315 #if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
4316    Evas_Engine_Info_Software_8_X11 *einfo;
4317    Ecore_Evas *ee;
4318    int argb = 0;
4319    int rmethod;
4320    static int redraw_debug = -1;
4321
4322    rmethod = evas_render_method_lookup("software_8_x11");
4323    if (!rmethod) return NULL;
4324    if (!ecore_x_init(disp_name)) return NULL;
4325    ee = calloc(1, sizeof(Ecore_Evas));
4326    if (!ee) return NULL;
4327
4328    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
4329
4330    _ecore_evas_x_init();
4331
4332    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
4333
4334    ee->driver = "software_8_x11";
4335    if (disp_name) ee->name = strdup(disp_name);
4336
4337    if (w < 1) w = 1;
4338    if (h < 1) h = 1;
4339    ee->x = x;
4340    ee->y = y;
4341    ee->w = w;
4342    ee->h = h;
4343    ee->req.x = ee->x;
4344    ee->req.y = ee->y;
4345    ee->req.w = ee->w;
4346    ee->req.h = ee->h;
4347
4348    ee->prop.max.w = 32767;
4349    ee->prop.max.h = 32767;
4350    ee->prop.layer = 4;
4351    ee->prop.request_pos = 0;
4352    ee->prop.sticky = 0;
4353    ee->engine.x.state.sticky = 0;
4354
4355    /* init evas here */
4356    ee->evas = evas_new();
4357    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_PRE, _ecore_evas_x_flush_pre, ee);
4358    evas_event_callback_add(ee->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _ecore_evas_x_flush_post, ee);
4359    evas_data_attach_set(ee->evas, ee);
4360    evas_output_method_set(ee->evas, rmethod);
4361    evas_output_size_set(ee->evas, w, h);
4362    evas_output_viewport_set(ee->evas, 0, 0, w, h);
4363
4364    ee->engine.x.win_root = parent;
4365    //   if (parent != 0)
4366    //     {
4367    //       /* FIXME: round trip in ecore_x_window_argb_get */
4368    //        if (ecore_x_window_argb_get(parent))
4369    //          {
4370    //             ee->engine.x.win = ecore_x_window_argb_new(parent, x, y, w, h);
4371    //             argb = 1;
4372    //          }
4373    //        else
4374    //          ee->engine.x.win = ecore_x_window_new(parent, x, y, w, h);
4375    //     }
4376    //   else
4377    ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
4378    if (getenv("DESKTOP_STARTUP_ID"))
4379      {
4380         ecore_x_netwm_startup_id_set(ee->prop.window,
4381               getenv("DESKTOP_STARTUP_ID"));
4382         /* NB: on linux this may simply empty the env as opposed to completely
4383          * unset it to being empty - unsure as solartis libc crashes looking
4384          * for the '=' char */
4385         //        putenv((char*)"DESKTOP_STARTUP_ID=");
4386      }
4387    einfo = (Evas_Engine_Info_Software_8_X11 *)evas_engine_info_get(ee->evas);
4388    if (einfo)
4389      {
4390         xcb_screen_iterator_t iter;
4391         xcb_screen_t         *screen;
4392
4393         /* FIXME: this is inefficient as its a round trip */
4394         //einfo->info.backend = 1;
4395         screen = ecore_x_default_screen_get();
4396         iter = xcb_setup_roots_iterator (xcb_get_setup (ecore_x_connection_get()));
4397         if (iter.rem > 1)
4398           {
4399              xcb_get_geometry_cookie_t cookie;
4400              xcb_get_geometry_reply_t *reply;
4401              Ecore_X_Window           *roots;
4402              int                       num;
4403              uint8_t                   i;
4404
4405              num = 0;
4406              cookie = xcb_get_geometry_unchecked(ecore_x_connection_get(), parent);
4407              roots = ecore_x_window_root_list(&num);
4408              if (roots)
4409                {
4410                   reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
4411
4412                   if (reply)
4413                     {
4414                        for (i = 0; i < num; xcb_screen_next (&iter), i++)
4415                          {
4416                             if (reply->root == roots[i])
4417                               {
4418                                  screen = iter.data;
4419                                  break;
4420                               }
4421                          }
4422                        free(reply);
4423                     }
4424                   free(roots);
4425                }
4426              else
4427                {
4428                   reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
4429                   if (reply) free(reply);
4430                }
4431           }
4432
4433         if (redraw_debug < 0)
4434           {
4435              if (getenv("REDRAW_DEBUG"))
4436                redraw_debug = atoi(getenv("REDRAW_DEBUG"));
4437              else
4438                redraw_debug = 0;
4439           }
4440         einfo->info.connection = ecore_x_connection_get();
4441         einfo->info.screen = screen;
4442         einfo->info.drawable = ee->prop.window;
4443         if (argb)
4444           {
4445              /* FIXME: round trip */
4446              xcb_get_geometry_cookie_t          cookie_geom;
4447              xcb_get_window_attributes_cookie_t cookie_attr;
4448              xcb_get_geometry_reply_t          *reply_geom;
4449              xcb_get_window_attributes_reply_t *reply_attr;
4450
4451              cookie_geom = xcb_get_geometry_unchecked(ecore_x_connection_get(), ee->prop.window);
4452              cookie_attr = xcb_get_window_attributes_unchecked(ecore_x_connection_get(), ee->prop.window);
4453
4454              reply_geom = xcb_get_geometry_reply(ecore_x_connection_get(), cookie_geom, NULL);
4455              reply_attr = xcb_get_window_attributes_reply(ecore_x_connection_get(), cookie_attr, NULL);
4456              if (reply_attr && reply_geom)
4457                {
4458                   einfo->info.visual   = xcb_visualtype_get(ecore_x_default_screen_get(), reply_attr->visual);
4459                   einfo->info.colormap = reply_attr->colormap;
4460                   einfo->info.depth    = reply_geom->depth;
4461                   einfo->info.destination_alpha = 1;
4462                   free(reply_geom);
4463                   free(reply_attr);
4464                }
4465           }
4466         else
4467           {
4468              xcb_screen_t *screen;
4469
4470              screen = ecore_x_default_screen_get();
4471              einfo->info.visual   = xcb_visualtype_get(screen, screen->root_visual);
4472              einfo->info.colormap = screen->default_colormap;
4473              einfo->info.depth    = screen->root_depth;
4474              einfo->info.destination_alpha = 0;
4475           }
4476         einfo->info.rotation = 0;
4477         einfo->info.debug    = redraw_debug;
4478         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
4479           {
4480              ERR("evas_engine_info_set() init engine '%s' failed.", ee->driver);
4481              ecore_evas_free(ee);
4482              return NULL;
4483           }
4484      }
4485
4486    ecore_x_icccm_hints_set(ee->prop.window,
4487                            1 /* accepts_focus */,
4488                            ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
4489                            0 /* icon_pixmap */,
4490                            0 /* icon_mask */,
4491                            0 /* icon_window */,
4492                            0 /* window_group */,
4493                            0 /* is_urgent */);
4494    _ecore_evas_x_group_leader_set(ee);
4495    ecore_x_window_defaults_set(ee->prop.window);
4496    _ecore_evas_x_protocols_set(ee);
4497    _ecore_evas_x_sync_set(ee);
4498
4499    ee->engine.func->fn_render = _ecore_evas_x_render;
4500    _ecore_evas_register(ee);
4501    ecore_x_input_multi_select(ee->prop.window);
4502    ecore_event_window_register(ee->prop.window, ee, ee->evas,
4503                                (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
4504                                (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
4505                                (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
4506                                (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
4507
4508    return ee;
4509 #else
4510    return NULL;
4511    disp_name = NULL;
4512    parent = 0;
4513    x = 0;
4514    y = 0;
4515    w = 0;
4516    h = 0;
4517 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_8_X11 */
4518 }
4519
4520 /**
4521  * To be documented.
4522  *
4523  * FIXME: To be fixed.
4524  */
4525 EAPI Ecore_X_Window
4526 ecore_evas_software_x11_8_window_get(const Ecore_Evas *ee)
4527 {
4528 #if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
4529    return (Ecore_X_Window) ecore_evas_window_get(ee);
4530 #else
4531    return 0;
4532    ee = NULL;
4533 #endif
4534 }
4535
4536 /**
4537  * To be documented.
4538  *
4539  * FIXME: To be fixed.
4540  */
4541 EAPI Ecore_X_Window
4542 ecore_evas_software_x11_8_subwindow_get(const Ecore_Evas *ee)
4543 {
4544 #if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
4545    return (Ecore_X_Window) ecore_evas_window_get(ee);
4546 #else
4547    return 0;
4548    ee = NULL;
4549 #endif
4550 }
4551
4552 /**
4553  * To be documented.
4554  *
4555  * FIXME: To be fixed.
4556  */
4557 EAPI void
4558 ecore_evas_software_x11_8_direct_resize_set(Ecore_Evas *ee, Eina_Bool on)
4559 {
4560 #if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
4561    ee->engine.x.direct_resize = on;
4562    if (ee->prop.avoid_damage)
4563      {
4564         if (ee->engine.x.direct_resize)
4565           {
4566              /* turn this off for now
4567                 ee->engine.x.using_bg_pixmap = 1;
4568                 ecore_x_window_pixmap_set(ee->engine.x.win, ee->engine.x.pmap);
4569                 */
4570           }
4571         else
4572           {
4573              /* turn this off too- bg pixmap is controlled by avoid damage directly
4574                 ee->engine.x.using_bg_pixmap = 0;
4575                 ecore_x_window_pixmap_set(ee->engine.x.win, 0);
4576                 ecore_x_window_area_expose(ee->engine.x.win, 0, 0, ee->w, ee->h);
4577                 */
4578           }
4579      }
4580 #else
4581    return;
4582    ee = NULL;
4583    on = 0;
4584 #endif
4585 }
4586
4587 /**
4588  * To be documented.
4589  *
4590  * FIXME: To be fixed.
4591  */
4592 EAPI Eina_Bool
4593 ecore_evas_software_x11_8_direct_resize_get(const Ecore_Evas *ee)
4594 {
4595 #if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
4596    return ee->engine.x.direct_resize;
4597 #else
4598    return 0;
4599    ee = NULL;
4600 #endif
4601 }
4602
4603 /**
4604  * To be documented.
4605  *
4606  * FIXME: To be fixed.
4607  */
4608 EAPI void
4609 ecore_evas_software_x11_8_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
4610 {
4611 #if defined (BUILD_ECORE_EVAS_SOFTWARE_8_X11)
4612    Ecore_X_Window *winp;
4613
4614    winp = malloc(sizeof(Ecore_X_Window));
4615    if (winp)
4616      {
4617         *winp = win;
4618         ee->engine.x.win_extra = eina_list_append(ee->engine.x.win_extra, winp);
4619         ecore_x_input_multi_select(win);
4620         ecore_event_window_register(win, ee, ee->evas,
4621                                     (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process,
4622                                     (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process,
4623                                     (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process,
4624                                     (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
4625      }
4626 #else
4627    return;
4628    ee = NULL;
4629    win = 0;
4630 #endif
4631 }
4632
4633 EAPI void
4634 ecore_evas_x11_leader_set(Ecore_Evas *ee, Ecore_X_Window win)
4635 {
4636 #ifdef BUILD_ECORE_EVAS_X11
4637    _ecore_evas_x_group_leader_unset(ee);
4638    ee->engine.x.leader = win;
4639    _ecore_evas_x_group_leader_update(ee);
4640 #else
4641    return;
4642    ee = NULL;
4643    win = 0;
4644 #endif
4645 }
4646
4647 EAPI Ecore_X_Window
4648 ecore_evas_x11_leader_get(Ecore_Evas *ee)
4649 {
4650 #ifdef BUILD_ECORE_EVAS_X11
4651    return ee->engine.x.leader;
4652 #else
4653    return 0;
4654    ee = NULL;
4655 #endif
4656 }
4657
4658 EAPI void
4659 ecore_evas_x11_leader_default_set(Ecore_Evas *ee)
4660 {
4661 #ifdef BUILD_ECORE_EVAS_X11
4662    _ecore_evas_x_group_leader_unset(ee);
4663    _ecore_evas_x_group_leader_set(ee);
4664 #else
4665    return;
4666    ee = NULL;
4667 #endif
4668 }
4669
4670 #ifdef BUILD_ECORE_EVAS_X11
4671 static Eina_Bool
4672 _ecore_evas_x11_convert_rectangle_with_angle(Ecore_Evas *ee, Ecore_X_Rectangle *dst_rect, Ecore_X_Rectangle *src_rect)
4673 {
4674    if (!src_rect || !dst_rect) return 0;
4675
4676    if (ee->rotation == 0)
4677      {
4678         dst_rect->x = src_rect->x;
4679         dst_rect->y = src_rect->y;
4680         dst_rect->width = src_rect->width;
4681         dst_rect->height = src_rect->height;
4682      }
4683    else if (ee->rotation == 90)
4684      {
4685         dst_rect->x = src_rect->y;
4686         dst_rect->y = ee->req.h - src_rect->x - src_rect->width;
4687         dst_rect->width = src_rect->height;
4688         dst_rect->height = src_rect->width;
4689      }
4690    else if (ee->rotation == 180)
4691      {
4692         dst_rect->x = ee->req.w - src_rect->x - src_rect->width;
4693         dst_rect->y = ee->req.h - src_rect->y - src_rect->height;
4694         dst_rect->width = src_rect->width;
4695         dst_rect->height = src_rect->height;
4696      }
4697    else if (ee->rotation == 270)
4698      {
4699         dst_rect->x = ee->req.w - src_rect->y - src_rect->height;
4700         dst_rect->y = src_rect->x;
4701         dst_rect->width = src_rect->height;
4702         dst_rect->height = src_rect->width;
4703      }
4704    else
4705      {
4706         return 0;
4707      }
4708
4709    return 1;
4710 }
4711 #endif
4712
4713 EAPI void
4714 ecore_evas_x11_shape_input_rectangle_set(Ecore_Evas *ee, int x, int y, int w, int h)
4715 {
4716 #ifdef BUILD_ECORE_EVAS_X11
4717    Eina_Bool ret;
4718    Ecore_X_Rectangle src_rect;
4719    Ecore_X_Rectangle dst_rect;
4720
4721    if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
4722      {
4723         ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
4724                          "ecore_evas_x11_shape_input_rectangle_set");
4725         return;
4726      }
4727
4728    src_rect.x = x;
4729    src_rect.y = y;
4730    src_rect.width = w;
4731    src_rect.height = h;
4732
4733    ret = _ecore_evas_x11_convert_rectangle_with_angle(ee, &dst_rect, &src_rect);
4734
4735    if (!ee->engine.x.win_shaped_input)
4736       ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, 0, 0, 1, 1);
4737
4738    if (ret)
4739       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);
4740 #else
4741    return;
4742    ee = NULL;
4743    x = 0;
4744    y = 0;
4745    w = 0;
4746    h = 0;
4747 #endif
4748 }
4749
4750 EAPI void
4751 ecore_evas_x11_shape_input_rectangle_add(Ecore_Evas *ee, int x, int y, int w, int h)
4752 {
4753 #ifdef BUILD_ECORE_EVAS_X11
4754    Eina_Bool ret;
4755    Ecore_X_Rectangle src_rect;
4756    Ecore_X_Rectangle dst_rect;
4757
4758    if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
4759      {
4760         ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
4761                          "ecore_evas_x11_shape_input_rectangle_add");
4762         return;
4763      }
4764
4765    src_rect.x = x;
4766    src_rect.y = y;
4767    src_rect.width = w;
4768    src_rect.height = h;
4769
4770    ret = _ecore_evas_x11_convert_rectangle_with_angle(ee, &dst_rect, &src_rect);
4771
4772    if (!ee->engine.x.win_shaped_input)
4773       ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, 0, 0, 1, 1);
4774
4775    if (ret)
4776       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);
4777 #else
4778    return;
4779    ee = NULL;
4780    x = 0;
4781    y = 0;
4782    w = 0;
4783    h = 0;
4784 #endif
4785 }
4786
4787 EAPI void
4788 ecore_evas_x11_shape_input_rectangle_subtract(Ecore_Evas *ee, int x, int y, int w, int h)
4789 {
4790 #ifdef BUILD_ECORE_EVAS_X11
4791    Eina_Bool ret;
4792    Ecore_X_Rectangle src_rect;
4793    Ecore_X_Rectangle dst_rect;
4794
4795    if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
4796      {
4797         ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
4798                          "ecore_evas_x11_shape_input_rectangle_subtract");
4799         return;
4800      }
4801
4802    src_rect.x = x;
4803    src_rect.y = y;
4804    src_rect.width = w;
4805    src_rect.height = h;
4806
4807    ret = _ecore_evas_x11_convert_rectangle_with_angle(ee, &dst_rect, &src_rect);
4808
4809    if (!ee->engine.x.win_shaped_input)
4810       ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, 0, 0, 1, 1);
4811
4812    if (ret)
4813       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);
4814 #else
4815    return;
4816    ee = NULL;
4817    x = 0;
4818    y = 0;
4819    w = 0;
4820    h = 0;
4821 #endif
4822 }
4823
4824 EAPI void
4825 ecore_evas_x11_shape_input_empty(Ecore_Evas *ee)
4826 {
4827 #ifdef BUILD_ECORE_EVAS_X11
4828    if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
4829      {
4830         ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
4831                          "ecore_evas_x11_shape_input_empty");
4832         return;
4833      }
4834
4835    if (!ee->engine.x.win_shaped_input)
4836       ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, 0, 0, 1, 1);
4837
4838    ecore_x_window_shape_input_rectangle_set(ee->engine.x.win_shaped_input, 0, 0, 0, 0);
4839 #else
4840    return;
4841    ee = NULL;
4842 #endif
4843 }
4844
4845 EAPI void
4846 ecore_evas_x11_shape_input_reset(Ecore_Evas *ee)
4847 {
4848 #ifdef BUILD_ECORE_EVAS_X11
4849    if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
4850      {
4851         ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
4852                          "ecore_evas_x11_shape_input_reset");
4853         return;
4854      }
4855
4856    if (!ee->engine.x.win_shaped_input)
4857       ee->engine.x.win_shaped_input = ecore_x_window_override_new(ee->engine.x.win_root, 0, 0, 1, 1);
4858
4859    ecore_x_window_shape_input_rectangle_set(ee->engine.x.win_shaped_input, 0, 0, 65535, 65535);
4860 #else
4861    return;
4862    ee = NULL;
4863 #endif
4864 }
4865
4866 EAPI void
4867 ecore_evas_x11_shape_input_apply(Ecore_Evas *ee)
4868 {
4869 #ifdef BUILD_ECORE_EVAS_X11
4870    if (!ECORE_MAGIC_CHECK(ee, ECORE_MAGIC_EVAS))
4871      {
4872         ECORE_MAGIC_FAIL(ee, ECORE_MAGIC_EVAS,
4873                          "ecore_evas_x11_shape_input_apply");
4874         return;
4875      }
4876
4877    if (!ee->engine.x.win_shaped_input) return;
4878
4879    ecore_x_window_shape_input_window_set(ee->prop.window, ee->engine.x.win_shaped_input);
4880 #else
4881    return;
4882    ee = NULL;
4883 #endif
4884 }
4885