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