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