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