multitouch support for xi2 and floating xi devices
[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_x_input_multi_select(ee->prop.window);
1512         ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
1513         if (ee->prop.borderless)
1514           ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
1515         if (ee->visible) ecore_x_window_show(ee->prop.window);
1516         if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
1517         if (ee->prop.title)
1518           {
1519              ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
1520              ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
1521           }
1522         ecore_x_icccm_hints_set(ee->prop.window,
1523                                 1 /* accepts_focus */,
1524                                 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
1525                                 0 /* icon_pixmap */,
1526                                 0 /* icon_mask */,
1527                                 0 /* icon_window */,
1528                                 0 /* window_group */,
1529                                 0 /* is_urgent */);
1530 #endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
1531      }
1532    else if (!strcmp(ee->driver, "xrender_x11"))
1533      {
1534 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
1535         Evas_Engine_Info_XRender_X11 *einfo;
1536
1537         einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
1538         if (!einfo) return;
1539         if (!ecore_x_composite_query()) return;
1540
1541         ee->shaped = 0;
1542         ee->alpha = alpha;
1543         ecore_x_window_free(ee->prop.window);
1544         ecore_event_window_unregister(ee->prop.window);
1545         if (ee->alpha)
1546           {
1547              if (ee->prop.override)
1548                ee->prop.window = ecore_x_window_override_argb_new(ee->engine.x.win_root, ee->x, ee->y, ee->w, ee->h);
1549              else
1550                ee->prop.window = ecore_x_window_argb_new(ee->engine.x.win_root, ee->x, ee->y, ee->w, ee->h);
1551              if (!ee->engine.x.mask)
1552                ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
1553           }
1554         else
1555           {
1556              if (ee->prop.override)
1557                ee->prop.window = ecore_x_window_override_new(ee->engine.x.win_root, ee->x, ee->y, ee->w, ee->h);
1558              else
1559                ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->x, ee->y, ee->w, ee->h);
1560              if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1561              ee->engine.x.mask = 0;
1562              ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1563           }
1564
1565         einfo->info.destination_alpha = alpha;
1566
1567 # ifdef BUILD_ECORE_EVAS_XRENDER_XCB
1568         cookie_attr = xcb_get_window_attributes_unchecked(ecore_x_connection_get(), ee->prop.window);
1569         reply_attr = xcb_get_window_attributes_reply(ecore_x_connection_get(), cookie_attr, NULL);
1570
1571         einfo->info.visual = reply_attr->visual;
1572         free(reply_attr);
1573 # else
1574         XGetWindowAttributes(ecore_x_display_get(), ee->prop.window, &att);
1575         einfo->info.visual = att.visual;
1576 # endif /* ! BUILD_ECORE_EVAS_XRENDER_XCB */
1577
1578 //      if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1579 //      ee->engine.x.mask = 0;
1580         einfo->info.mask = ee->engine.x.mask;
1581         einfo->info.drawable = ee->prop.window;
1582         evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
1583         evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1584         ecore_x_window_shape_mask_set(ee->prop.window, 0);
1585         ecore_x_input_multi_select(ee->prop.window);
1586         ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
1587         if (ee->prop.borderless)
1588           ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
1589         if (ee->visible) ecore_x_window_show(ee->prop.window);
1590         if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
1591         if (ee->prop.title)
1592           {
1593              ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
1594              ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
1595           }
1596         ecore_x_icccm_hints_set(ee->prop.window,
1597                                 1 /* accepts_focus */,
1598                                 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
1599                                 0 /* icon_pixmap */,
1600                                 0 /* icon_mask */,
1601                                 0 /* icon_window */,
1602                                 0 /* window_group */,
1603                                 0 /* is_urgent */);
1604 #endif /* BUILD_ECORE_EVAS_XRENDER_X11 || BUILD_ECORE_EVAS_XRENDER_XCB */
1605      }
1606    else if (!strcmp(ee->driver, "software_16_x11"))
1607      {
1608 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
1609         Evas_Engine_Info_Software_16_X11 *einfo;
1610
1611         einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
1612         if (!einfo) return;
1613
1614         ee->shaped = 0;
1615         ee->alpha = alpha;
1616         ecore_x_window_free(ee->prop.window);
1617         ecore_event_window_unregister(ee->prop.window);
1618         if (ee->alpha)
1619           {
1620              if (ee->prop.override)
1621                ee->prop.window = ecore_x_window_override_argb_new(ee->engine.x.win_root, ee->x, ee->y, ee->w, ee->h);
1622              else
1623                ee->prop.window = ecore_x_window_argb_new(ee->engine.x.win_root, ee->x, ee->y, ee->w, ee->h);
1624              if (!ee->engine.x.mask)
1625                ee->engine.x.mask = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 1);
1626           }
1627         else
1628           {
1629              if (ee->prop.override)
1630                ee->prop.window = ecore_x_window_override_new(ee->engine.x.win_root, ee->x, ee->y, ee->w, ee->h);
1631              else
1632                ee->prop.window = ecore_x_window_new(ee->engine.x.win_root, ee->x, ee->y, ee->w, ee->h);
1633              if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1634              ee->engine.x.mask = 0;
1635              ecore_x_window_shape_input_mask_set(ee->prop.window, 0);
1636           }
1637
1638 # if 0 /* XXX no alpha window support for software_16_x11 */
1639         einfo->info.destination_alpha = alpha;
1640 # endif /* XXX no alpha window support for software_16_x11 */
1641
1642 # if 0 /* XXX no shaped window support for software_16_x11 */
1643 //      if (ee->engine.x.mask) ecore_x_pixmap_free(ee->engine.x.mask);
1644 //      ee->engine.x.mask = 0;
1645         einfo->info.mask = ee->engine.x.mask;
1646 # endif /* XXX no shaped window support for software_16_x11 */
1647
1648         einfo->info.drawable = ee->prop.window;
1649         evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
1650         evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
1651         ecore_x_window_shape_mask_set(ee->prop.window, 0);
1652         ecore_x_input_multi_select(ee->prop.window);
1653         ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
1654         if (ee->prop.borderless)
1655           ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
1656         if (ee->visible) ecore_x_window_show(ee->prop.window);
1657         if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
1658         if (ee->prop.title)
1659           {
1660              ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
1661              ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
1662           }
1663         ecore_x_icccm_hints_set(ee->prop.window,
1664                                 1 /* accepts_focus */,
1665                                 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
1666                                 0 /* icon_pixmap */,
1667                                 0 /* icon_mask */,
1668                                 0 /* icon_window */,
1669                                 0 /* window_group */,
1670                                 0 /* is_urgent */);
1671 #endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
1672      }
1673 }
1674 #endif /* BUILD_ECORE_EVAS_X11 */
1675
1676 #ifdef BUILD_ECORE_EVAS_X11
1677 static void
1678 _ecore_evas_x_show(Ecore_Evas *ee)
1679 {
1680    ee->should_be_visible = 1;
1681    if (ee->prop.avoid_damage)
1682      _ecore_evas_x_render(ee);
1683    ecore_x_window_show(ee->prop.window);
1684    if (ee->prop.fullscreen)
1685      ecore_x_window_focus(ee->prop.window);
1686 }
1687
1688 static void
1689 _ecore_evas_x_hide(Ecore_Evas *ee)
1690 {
1691    ecore_x_window_hide(ee->prop.window);
1692    ee->should_be_visible = 0;
1693 }
1694
1695 static void
1696 _ecore_evas_x_raise(Ecore_Evas *ee)
1697 {
1698    if (!ee->prop.fullscreen)
1699      ecore_x_window_raise(ee->prop.window);
1700    else
1701      ecore_x_window_raise(ee->prop.window);
1702 }
1703
1704 static void
1705 _ecore_evas_x_lower(Ecore_Evas *ee)
1706 {
1707    if (!ee->prop.fullscreen)
1708      ecore_x_window_lower(ee->prop.window);
1709    else
1710      ecore_x_window_lower(ee->prop.window);
1711 }
1712
1713 static void
1714 _ecore_evas_x_activate(Ecore_Evas *ee)
1715 {
1716    ecore_x_netwm_client_active_request(ee->engine.x.win_root,
1717                                        ee->prop.window, 2, 0);
1718 }
1719
1720 static void
1721 _ecore_evas_x_title_set(Ecore_Evas *ee, const char *t)
1722 {
1723    if (ee->prop.title) free(ee->prop.title);
1724    ee->prop.title = NULL;
1725    if (t) ee->prop.title = strdup(t);
1726    ecore_x_icccm_title_set(ee->prop.window, ee->prop.title);
1727    ecore_x_netwm_name_set(ee->prop.window, ee->prop.title);
1728 }
1729
1730 static void
1731 _ecore_evas_x_name_class_set(Ecore_Evas *ee, const char *n, const char *c)
1732 {
1733    if (ee->prop.name) free(ee->prop.name);
1734    if (ee->prop.clas) free(ee->prop.clas);
1735    ee->prop.name = NULL;
1736    ee->prop.clas = NULL;
1737    if (n) ee->prop.name = strdup(n);
1738    if (c) ee->prop.clas = strdup(c);
1739    ecore_x_icccm_name_class_set(ee->prop.window, ee->prop.name, ee->prop.clas);
1740 }
1741
1742 static void
1743 _ecore_evas_x_size_min_set(Ecore_Evas *ee, int w, int h)
1744 {
1745    if (w < 0) w = 0;
1746    if (h < 0) h = 0;
1747    if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return;
1748    ee->prop.min.w = w;
1749    ee->prop.min.h = h;
1750    _ecore_evas_x_size_pos_hints_update(ee);
1751 }
1752
1753 static void
1754 _ecore_evas_x_size_max_set(Ecore_Evas *ee, int w, int h)
1755 {
1756    if (w < 0) w = 0;
1757    if (h < 0) h = 0;
1758    if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return;
1759    ee->prop.max.w = w;
1760    ee->prop.max.h = h;
1761    _ecore_evas_x_size_pos_hints_update(ee);
1762 }
1763
1764 static void
1765 _ecore_evas_x_size_base_set(Ecore_Evas *ee, int w, int h)
1766 {
1767    if (w < 0) w = 0;
1768    if (h < 0) h = 0;
1769    if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return;
1770    ee->prop.base.w = w;
1771    ee->prop.base.h = h;
1772    _ecore_evas_x_size_pos_hints_update(ee);
1773 }
1774
1775 static void
1776 _ecore_evas_x_size_step_set(Ecore_Evas *ee, int w, int h)
1777 {
1778    if (w < 1) w = 1;
1779    if (h < 1) h = 1;
1780    if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return;
1781    ee->prop.step.w = w;
1782    ee->prop.step.h = h;
1783    _ecore_evas_x_size_pos_hints_update(ee);
1784 }
1785
1786 static void
1787 _ecore_evas_object_cursor_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1788 {
1789    Ecore_Evas *ee;
1790
1791    ee = data;
1792    if (ee)
1793      ee->prop.cursor.object = NULL;
1794 }
1795
1796 static void
1797 _ecore_evas_x_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int layer, int hot_x, int hot_y)
1798 {
1799    int x, y;
1800
1801    if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
1802
1803    if (obj == NULL)
1804      {
1805         ee->prop.cursor.object = NULL;
1806         ee->prop.cursor.layer = 0;
1807         ee->prop.cursor.hot.x = 0;
1808         ee->prop.cursor.hot.y = 0;
1809         ecore_x_window_cursor_show(ee->prop.window, 1);
1810         return;
1811      }
1812
1813    ee->prop.cursor.object = obj;
1814    ee->prop.cursor.layer = layer;
1815    ee->prop.cursor.hot.x = hot_x;
1816    ee->prop.cursor.hot.y = hot_y;
1817
1818    ecore_x_window_cursor_show(ee->prop.window, 0);
1819
1820    evas_pointer_output_xy_get(ee->evas, &x, &y);
1821    evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
1822    evas_object_move(ee->prop.cursor.object,
1823                     x - ee->prop.cursor.hot.x,
1824                     y - ee->prop.cursor.hot.y);
1825    evas_object_pass_events_set(ee->prop.cursor.object, 1);
1826    if (evas_pointer_inside_get(ee->evas))
1827      evas_object_show(ee->prop.cursor.object);
1828
1829    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _ecore_evas_object_cursor_del, ee);
1830 }
1831
1832 /*
1833  * @param ee
1834  * @param layer If < 3, @a ee will be put below all other windows.
1835  *              If > 5, @a ee will be "always-on-top"
1836  *              If = 4, @a ee will be put in the default layer.
1837  *              Acceptable values range from 1 to 255 (0 reserved for
1838  *              desktop windows)
1839  */
1840 static void
1841 _ecore_evas_x_layer_set(Ecore_Evas *ee, int layer)
1842 {
1843    if (ee->prop.layer == layer) return;
1844
1845    /* FIXME: Should this logic be here? */
1846    if (layer < 1)
1847      layer = 1;
1848    else if (layer > 255)
1849      layer = 255;
1850
1851    ee->prop.layer = layer;
1852    _ecore_evas_x_layer_update(ee);
1853 }
1854
1855 static void
1856 _ecore_evas_x_focus_set(Ecore_Evas *ee, int on __UNUSED__)
1857 {
1858    ecore_x_window_focus(ee->prop.window);
1859 }
1860
1861 static void
1862 _ecore_evas_x_iconified_set(Ecore_Evas *ee, int on)
1863 {
1864 //   if (((ee->prop.iconified) && (on)) ||
1865 //       ((!ee->prop.iconified) && (!on))) return;
1866    ee->prop.iconified = on;
1867    if (on)
1868      {
1869         ecore_x_icccm_hints_set(ee->prop.window,
1870                                 1 /* accepts_focus */,
1871                                 ECORE_X_WINDOW_STATE_HINT_ICONIC /* initial_state */,
1872                                 0 /* icon_pixmap */,
1873                                 0 /* icon_mask */,
1874                                 0 /* icon_window */,
1875                                 0 /* window_group */,
1876                                 0 /* is_urgent */);
1877         ecore_x_icccm_iconic_request_send(ee->prop.window, ee->engine.x.win_root);
1878      }
1879    else
1880      {
1881         ecore_x_icccm_hints_set(ee->prop.window,
1882                                 1 /* accepts_focus */,
1883                                 ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
1884                                 0 /* icon_pixmap */,
1885                                 0 /* icon_mask */,
1886                                 0 /* icon_window */,
1887                                 0 /* window_group */,
1888                                 0 /* is_urgent */);
1889         ecore_evas_show(ee);
1890      }
1891 }
1892
1893 static void
1894 _ecore_evas_x_borderless_set(Ecore_Evas *ee, int on)
1895 {
1896    if (((ee->prop.borderless) && (on)) ||
1897        ((!ee->prop.borderless) && (!on))) return;
1898    ee->prop.borderless = on;
1899    ecore_x_mwm_borderless_set(ee->prop.window, ee->prop.borderless);
1900 }
1901
1902 /* FIXME: This function changes the initial state of the ee
1903  * whilest the iconic function changes the current state! */
1904 static void
1905 _ecore_evas_x_withdrawn_set(Ecore_Evas *ee, int withdrawn)
1906 {
1907    Ecore_X_Window_State_Hint hint;
1908
1909    if ((ee->prop.withdrawn && withdrawn) ||
1910       (!ee->prop.withdrawn && !withdrawn)) return;
1911
1912    ee->prop.withdrawn = withdrawn;
1913    if (withdrawn)
1914      hint = ECORE_X_WINDOW_STATE_HINT_WITHDRAWN;
1915    else
1916      hint = ECORE_X_WINDOW_STATE_HINT_NORMAL;
1917
1918    ecore_x_icccm_hints_set(ee->prop.window,
1919                            1 /* accepts_focus */,
1920                            hint /* initial_state */,
1921                            0 /* icon_pixmap */,
1922                            0 /* icon_mask */,
1923                            0 /* icon_window */,
1924                            0 /* window_group */,
1925                            0 /* is_urgent */);
1926 }
1927
1928 static void
1929 _ecore_evas_x_sticky_set(Ecore_Evas *ee, int sticky)
1930 {
1931    if ((ee->prop.sticky && sticky) ||
1932       (!ee->prop.sticky && !sticky)) return;
1933
1934    /* We dont want to set prop.sticky here as it will cause
1935     * the sticky callback not to get called. Its set on the
1936     * property change event.
1937     * ee->prop.sticky = sticky;
1938     */
1939    ee->engine.x.state.sticky = sticky;
1940    if (ee->should_be_visible)
1941      ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root,
1942                                       ECORE_X_WINDOW_STATE_STICKY, -1, sticky);
1943    else
1944      _ecore_evas_x_state_update(ee);
1945 }
1946
1947 static void
1948 _ecore_evas_x_ignore_events_set(Ecore_Evas *ee, int ignore)
1949 {
1950    if ((ee->ignore_events && ignore) ||
1951        (!ee->ignore_events && !ignore)) return;
1952
1953    if (ignore)
1954      {
1955         ee->ignore_events = 1;
1956         if (ee->prop.window)
1957           ecore_x_window_ignore_set(ee->prop.window, 1);
1958      }
1959    else
1960      {
1961         ee->ignore_events = 0;
1962         if (ee->prop.window)
1963           ecore_x_window_ignore_set(ee->prop.window, 0);
1964      }
1965 }
1966
1967 /*
1968 static void
1969 _ecore_evas_x_reinit_win(Ecore_Evas *ee)
1970 {
1971    if (!strcmp(ee->driver, "software_x11"))
1972      {
1973 #ifdef BUILD_ECORE_EVAS_X11
1974         Evas_Engine_Info_Software_X11 *einfo;
1975
1976         einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
1977         if (einfo)
1978           {
1979              einfo->info.drawable = ee->prop.window;
1980              evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
1981           }
1982 #endif
1983      }
1984    else if (!strcmp(ee->driver, "xrender_x11"))
1985      {
1986 #ifdef BUILD_ECORE_EVAS_XRENDER_X11
1987         Evas_Engine_Info_XRender_X11 *einfo;
1988
1989         einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
1990         if (einfo)
1991           {
1992              einfo->info.drawable = ee->prop.window;
1993              evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
1994           }
1995 #endif
1996      }
1997    else if (!strcmp(ee->driver, "opengl_x11"))
1998      {
1999 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
2000         Evas_Engine_Info_GL_X11 *einfo;
2001
2002         einfo = (Evas_Engine_Info_GL_X11 *)evas_engine_info_get(ee->evas);
2003         if (einfo)
2004           {
2005              einfo->info.drawable = ee->prop.window;
2006              evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
2007           }
2008 #endif
2009      }
2010 }
2011 */
2012
2013 static void
2014 _ecore_evas_x_override_set(Ecore_Evas *ee, int on)
2015 {
2016    if (((ee->prop.override) && (on)) ||
2017        ((!ee->prop.override) && (!on))) return;
2018    ecore_x_window_hide(ee->prop.window);
2019    ecore_x_window_override_set(ee->prop.window, on);
2020    if (ee->visible) ecore_x_window_show(ee->prop.window);
2021    if (ee->prop.focused) ecore_x_window_focus(ee->prop.window);
2022    ee->prop.override = on;
2023 }
2024
2025 static void
2026 _ecore_evas_x_fullscreen_set(Ecore_Evas *ee, int on)
2027 {
2028    if ((ee->prop.fullscreen && on) ||
2029       (!ee->prop.fullscreen && !on)) return;
2030
2031    /* FIXME: Detect if WM is EWMH compliant and handle properly if not,
2032     * i.e. reposition, resize, and change borderless hint */
2033    ee->engine.x.state.fullscreen = on;
2034    if (ee->should_be_visible)
2035      ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root,
2036                                       ECORE_X_WINDOW_STATE_FULLSCREEN, -1, on);
2037    else
2038      _ecore_evas_x_state_update(ee);
2039 }
2040
2041 static void
2042 _ecore_evas_x_avoid_damage_set(Ecore_Evas *ee, int on)
2043 {
2044    if (ee->prop.avoid_damage == on) return;
2045    if (!strcmp(ee->driver, "opengl_x11")) return;
2046    if (!strcmp(ee->driver, "xrender_x11")) return;
2047
2048    if (!strcmp(ee->driver, "software_x11"))
2049      {
2050 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
2051         Evas_Engine_Info_Software_X11 *einfo;
2052
2053         ee->prop.avoid_damage = on;
2054         einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
2055         if (einfo)
2056           {
2057              if (ee->prop.avoid_damage)
2058                {
2059                   ee->engine.x.pmap = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, einfo->info.depth);
2060                   ee->engine.x.gc = ecore_x_gc_new(ee->engine.x.pmap, 0, NULL);
2061                   einfo->info.drawable = ee->engine.x.pmap;
2062                   evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
2063                   if ((ee->rotation == 90) || (ee->rotation == 270))
2064                     evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
2065                   else
2066                     evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
2067                   if (ee->prop.avoid_damage == ECORE_EVAS_AVOID_DAMAGE_BUILT_IN)
2068                     {
2069                        ee->engine.x.using_bg_pixmap = 1;
2070                        ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2071                        ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
2072                     }
2073                   if (ee->engine.x.direct_resize)
2074                     {
2075                        /* Turn this off for now
2076                           ee->engine.x.using_bg_pixmap = 1;
2077                           ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2078                        */
2079                     }
2080                }
2081              else
2082                {
2083                   if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap);
2084                   if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc);
2085                   if (ee->engine.x.using_bg_pixmap)
2086                     {
2087                        ecore_x_window_pixmap_set(ee->prop.window, 0);
2088                        ee->engine.x.using_bg_pixmap = 0;
2089                        ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
2090                     }
2091                   ee->engine.x.pmap = 0;
2092                   ee->engine.x.gc = 0;
2093                   einfo->info.drawable = ee->prop.window;
2094                   evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
2095                }
2096           }
2097 #endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
2098      }
2099    else if (!strcmp(ee->driver, "software_16_x11"))
2100      {
2101 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
2102         Evas_Engine_Info_Software_16_X11 *einfo;
2103         ee->prop.avoid_damage = on;
2104
2105         einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
2106         if (einfo)
2107           {
2108              if (ee->prop.avoid_damage)
2109                {
2110                   ee->engine.x.pmap = ecore_x_pixmap_new(ee->prop.window, ee->w, ee->h, 16);
2111                   ee->engine.x.gc = ecore_x_gc_new(ee->engine.x.pmap, 0, NULL);
2112                   einfo->info.drawable = ee->engine.x.pmap;
2113                   evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
2114                   if ((ee->rotation == 90) || (ee->rotation == 270))
2115                     evas_damage_rectangle_add(ee->evas, 0, 0, ee->h, ee->w);
2116                   else
2117                     evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
2118                   if (ee->engine.x.direct_resize)
2119                     {
2120                        /* Turn this off for now
2121                           ee->engine.x.using_bg_pixmap = 1;
2122                           ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2123                        */
2124                     }
2125                }
2126              else
2127                {
2128                   if (ee->engine.x.pmap) ecore_x_pixmap_free(ee->engine.x.pmap);
2129                   if (ee->engine.x.gc) ecore_x_gc_free(ee->engine.x.gc);
2130                   if (ee->engine.x.using_bg_pixmap)
2131                     {
2132                        ecore_x_window_pixmap_set(ee->prop.window, 0);
2133                        ee->engine.x.using_bg_pixmap = 0;
2134                     }
2135                   ee->engine.x.pmap = 0;
2136                   ee->engine.x.gc = 0;
2137                   einfo->info.drawable = ee->prop.window;
2138                   evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
2139                }
2140           }
2141 #endif /* BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
2142      }
2143 }
2144
2145 int
2146 _ecore_evas_x_shutdown(void)
2147 {
2148    _ecore_evas_init_count--;
2149    if (_ecore_evas_init_count == 0)
2150      {
2151         unsigned int i;
2152
2153         for (i = 0; i < sizeof(ecore_evas_event_handlers) / sizeof(Ecore_Event_Handler*); i++)
2154           ecore_event_handler_del(ecore_evas_event_handlers[i]);
2155         ecore_event_evas_shutdown();
2156      }
2157    if (_ecore_evas_init_count < 0) _ecore_evas_init_count = 0;
2158    return _ecore_evas_init_count;
2159 }
2160
2161 static Ecore_Evas_Engine_Func _ecore_x_engine_func =
2162 {
2163    _ecore_evas_x_free,
2164      NULL,
2165      NULL,
2166      NULL,
2167      NULL,
2168      _ecore_evas_x_callback_delete_request_set,
2169      NULL,
2170      NULL,
2171      NULL,
2172      NULL,
2173      NULL,
2174      NULL,
2175      NULL,
2176      NULL,
2177      NULL,
2178      _ecore_evas_x_move,
2179      _ecore_evas_x_managed_move,
2180      _ecore_evas_x_resize,
2181      _ecore_evas_x_move_resize,
2182      _ecore_evas_x_rotation_set,
2183      _ecore_evas_x_shaped_set,
2184      _ecore_evas_x_show,
2185      _ecore_evas_x_hide,
2186      _ecore_evas_x_raise,
2187      _ecore_evas_x_lower,
2188      _ecore_evas_x_activate,
2189      _ecore_evas_x_title_set,
2190      _ecore_evas_x_name_class_set,
2191      _ecore_evas_x_size_min_set,
2192      _ecore_evas_x_size_max_set,
2193      _ecore_evas_x_size_base_set,
2194      _ecore_evas_x_size_step_set,
2195      _ecore_evas_x_object_cursor_set,
2196      _ecore_evas_x_layer_set,
2197      _ecore_evas_x_focus_set,
2198      _ecore_evas_x_iconified_set,
2199      _ecore_evas_x_borderless_set,
2200      _ecore_evas_x_override_set,
2201      NULL,
2202      _ecore_evas_x_fullscreen_set,
2203      _ecore_evas_x_avoid_damage_set,
2204      _ecore_evas_x_withdrawn_set,
2205      _ecore_evas_x_sticky_set,
2206      _ecore_evas_x_ignore_events_set,
2207      _ecore_evas_x_alpha_set,
2208      
2209      NULL // render
2210 };
2211 #endif /* BUILD_ECORE_EVAS_X11 */
2212
2213 /*
2214  * FIXME: there are some round trips. Especially, we can split
2215  * ecore_x_init in 2 functions and supress some round trips.
2216  */
2217
2218 /**
2219  * To be documented.
2220  *
2221  * FIXME: To be fixed.
2222  */
2223 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
2224 EAPI Ecore_Evas *
2225 ecore_evas_software_x11_new(const char *disp_name, Ecore_X_Window parent,
2226                             int x, int y, int w, int h)
2227 {
2228    Evas_Engine_Info_Software_X11 *einfo;
2229    Ecore_Evas *ee;
2230    int argb = 0;
2231    int rmethod;
2232    static int redraw_debug = -1;
2233
2234    rmethod = evas_render_method_lookup("software_x11");
2235    if (!rmethod) return NULL;
2236    if (!ecore_x_init(disp_name)) return NULL;
2237    ee = calloc(1, sizeof(Ecore_Evas));
2238    if (!ee) return NULL;
2239
2240    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
2241
2242    _ecore_evas_x_init();
2243
2244    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
2245
2246    ee->driver = "software_x11";
2247    if (disp_name) ee->name = strdup(disp_name);
2248
2249    if (w < 1) w = 1;
2250    if (h < 1) h = 1;
2251    ee->x = x;
2252    ee->y = y;
2253    ee->w = w;
2254    ee->h = h;
2255
2256    ee->prop.max.w = 32767;
2257    ee->prop.max.h = 32767;
2258    ee->prop.layer = 4;
2259    ee->prop.request_pos = 0;
2260    ee->prop.sticky = 0;
2261    ee->engine.x.state.sticky = 0;
2262
2263    /* init evas here */
2264    ee->evas = evas_new();
2265    evas_data_attach_set(ee->evas, ee);
2266    evas_output_method_set(ee->evas, rmethod);
2267    evas_output_size_set(ee->evas, w, h);
2268    evas_output_viewport_set(ee->evas, 0, 0, w, h);
2269
2270    ee->engine.x.win_root = parent;
2271    ee->engine.x.screen_num = 0;
2272    
2273    if (parent != 0)
2274      {
2275         ee->engine.x.screen_num = 1; /* FIXME: get real scren # */
2276        /* FIXME: round trip in ecore_x_window_argb_get */
2277         if (ecore_x_window_argb_get(parent))
2278           {
2279              ee->prop.window = ecore_x_window_argb_new(parent, x, y, w, h);
2280              argb = 1;
2281           }
2282         else
2283           ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
2284      }
2285    else
2286      ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
2287    if (getenv("DESKTOP_STARTUP_ID"))
2288      {
2289         ecore_x_netwm_startup_id_set(ee->prop.window,
2290                                      getenv("DESKTOP_STARTUP_ID"));
2291         /* NB: on linux this may simply empty the env as opposed to completely
2292          * unset it to being empty - unsure as solartis libc crashes looking
2293          * for the '=' char */
2294 //      putenv((char*)"DESKTOP_STARTUP_ID=");
2295      }
2296    einfo = (Evas_Engine_Info_Software_X11 *)evas_engine_info_get(ee->evas);
2297    if (einfo)
2298      {
2299 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
2300         xcb_screen_iterator_t iter;
2301         xcb_screen_t         *screen;
2302 # else
2303         int screen;
2304 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
2305
2306         /* FIXME: this is inefficient as its a round trip */
2307 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
2308         screen = ecore_x_default_screen_get();
2309         iter = xcb_setup_roots_iterator (xcb_get_setup (ecore_x_connection_get()));
2310         if (iter.rem > 1)
2311           {
2312              xcb_get_geometry_cookie_t cookie;
2313              xcb_get_geometry_reply_t *reply;
2314              Ecore_X_Window           *roots;
2315              int                       num;
2316              uint8_t                   i;
2317
2318              num = 0;
2319              cookie = xcb_get_geometry_unchecked(ecore_x_connection_get(), parent);
2320              roots = ecore_x_window_root_list(&num);
2321              if (roots)
2322                {
2323                   reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
2324
2325                   if (reply)
2326                     {
2327                        for (i = 0; i < num; xcb_screen_next (&iter), i++)
2328                          {
2329                             if (reply->root == roots[i])
2330                               {
2331                                  screen = iter.data;
2332                                  break;
2333                               }
2334                          }
2335                        free(reply);
2336                     }
2337                   free(roots);
2338                }
2339              else
2340                {
2341                   reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
2342                   if (reply) free(reply);
2343                }
2344           }
2345 # else
2346         screen = DefaultScreen(ecore_x_display_get());
2347         if (ScreenCount(ecore_x_display_get()) > 1)
2348           {
2349              Ecore_X_Window *roots;
2350              int num, i;
2351
2352              num = 0;
2353              roots = ecore_x_window_root_list(&num);
2354              if (roots)
2355                {
2356                   XWindowAttributes at;
2357
2358                   if (XGetWindowAttributes(ecore_x_display_get(),
2359                                            parent, &at))
2360                     {
2361                        for (i = 0; i < num; i++)
2362                          {
2363                             if (at.root == roots[i])
2364                               {
2365                                  screen = i;
2366                                  break;
2367                               }
2368                          }
2369                     }
2370                   free(roots);
2371                }
2372           }
2373 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
2374
2375         if (redraw_debug < 0)
2376           {
2377              if (getenv("REDRAW_DEBUG"))
2378                redraw_debug = atoi(getenv("REDRAW_DEBUG"));
2379              else
2380                redraw_debug = 0;
2381           }
2382 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
2383         einfo->info.backend = EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XCB;
2384         einfo->info.connection = ecore_x_connection_get();
2385         einfo->info.screen = screen;
2386 # else
2387         einfo->info.backend = EVAS_ENGINE_INFO_SOFTWARE_X11_BACKEND_XLIB;
2388         einfo->info.connection = ecore_x_display_get();
2389         einfo->info.screen = NULL;
2390 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
2391         einfo->info.drawable = ee->prop.window;
2392         if (argb)
2393           {
2394         /* FIXME: round trip */
2395 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
2396              xcb_get_geometry_cookie_t          cookie_geom;
2397              xcb_get_window_attributes_cookie_t cookie_attr;
2398              xcb_get_geometry_reply_t          *reply_geom;
2399              xcb_get_window_attributes_reply_t *reply_attr;
2400
2401              cookie_geom = xcb_get_geometry_unchecked(ecore_x_connection_get(), ee->prop.window);
2402              cookie_attr = xcb_get_window_attributes_unchecked(ecore_x_connection_get(), ee->prop.window);
2403
2404              reply_geom = xcb_get_geometry_reply(ecore_x_connection_get(), cookie_geom, NULL);
2405              reply_attr = xcb_get_window_attributes_reply(ecore_x_connection_get(), cookie_attr, NULL);
2406              if (reply_attr && reply_geom)
2407                {
2408                   einfo->info.visual   = xcb_visualtype_get(ecore_x_default_screen_get(), reply_attr->visual);
2409                   einfo->info.colormap = reply_attr->colormap;
2410                   einfo->info.depth    = reply_geom->depth;
2411                   einfo->info.destination_alpha = 1;
2412                   free(reply_geom);
2413                   free(reply_attr);
2414                }
2415 # else
2416              XWindowAttributes at;
2417
2418              if (XGetWindowAttributes(ecore_x_display_get(), ee->prop.window,
2419                                       &at))
2420                {
2421                   einfo->info.visual   = at.visual;
2422                   einfo->info.colormap = at.colormap;
2423                   einfo->info.depth    = at.depth;
2424                   einfo->info.destination_alpha = 1;
2425                }
2426 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
2427           }
2428         else
2429           {
2430 # ifdef BUILD_ECORE_EVAS_SOFTWARE_XCB
2431              xcb_screen_t *screen;
2432
2433              screen = ecore_x_default_screen_get();
2434              einfo->info.visual   = xcb_visualtype_get(screen, screen->root_visual);
2435              einfo->info.colormap = screen->default_colormap;
2436              einfo->info.depth    = screen->root_depth;
2437 #else
2438              einfo->info.visual   = DefaultVisual(ecore_x_display_get(), screen);
2439              einfo->info.colormap = DefaultColormap(ecore_x_display_get(), screen);
2440              einfo->info.depth    = DefaultDepth(ecore_x_display_get(), screen);
2441 # endif /* ! BUILD_ECORE_EVAS_SOFTWARE_XCB */
2442              einfo->info.destination_alpha = 0;
2443           }
2444         einfo->info.rotation = 0;
2445         einfo->info.debug    = redraw_debug;
2446         evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
2447      }
2448    ecore_x_icccm_hints_set(ee->prop.window,
2449                            1 /* accepts_focus */,
2450                            ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2451                            0 /* icon_pixmap */,
2452                            0 /* icon_mask */,
2453                            0 /* icon_window */,
2454                            0 /* window_group */,
2455                            0 /* is_urgent */);
2456
2457    ee->engine.func->fn_render = _ecore_evas_x_render;
2458    _ecore_evas_register(ee);
2459    ecore_x_input_multi_select(ee->prop.window);
2460    ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
2461    return ee;
2462 }
2463 #else
2464 EAPI Ecore_Evas *
2465 ecore_evas_software_x11_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
2466                             int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
2467 {
2468    return NULL;
2469 }
2470 #endif
2471
2472 /**
2473  * To be documented.
2474  *
2475  * FIXME: To be fixed.
2476  */
2477 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
2478 EAPI Ecore_X_Window
2479 ecore_evas_software_x11_window_get(const Ecore_Evas *ee)
2480 {
2481    return (Ecore_X_Window) ecore_evas_window_get(ee);
2482 }
2483 #else
2484 EAPI Ecore_X_Window
2485 ecore_evas_software_x11_window_get(const Ecore_Evas *ee __UNUSED__)
2486 {
2487    return 0;
2488 }
2489 #endif
2490
2491 /**
2492  * To be documented.
2493  *
2494  * FIXME: To be fixed.
2495  */
2496 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
2497 EAPI void
2498 ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee, int on)
2499 {
2500    ee->engine.x.direct_resize = on;
2501    if (ee->prop.avoid_damage)
2502      {
2503         if (ee->engine.x.direct_resize)
2504           {
2505 /* turn this off for now
2506              ee->engine.x.using_bg_pixmap = 1;
2507              ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
2508  */
2509           }
2510         else
2511           {
2512 /* turn this off too- bg pixmap is controlled by avoid damage directly
2513              ee->engine.x.using_bg_pixmap = 0;
2514              ecore_x_window_pixmap_set(ee->prop.window, 0);
2515              ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
2516  */
2517           }
2518      }
2519 }
2520 #else
2521 EAPI void
2522 ecore_evas_software_x11_direct_resize_set(Ecore_Evas *ee __UNUSED__, int on __UNUSED__)
2523 {
2524 }
2525 #endif
2526
2527 /**
2528  * To be documented.
2529  *
2530  * FIXME: To be fixed.
2531  */
2532 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
2533 EAPI int
2534 ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee)
2535 {
2536    return ee->engine.x.direct_resize;
2537 }
2538 #else
2539 EAPI int
2540 ecore_evas_software_x11_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
2541 {
2542    return 0;
2543 }
2544 #endif
2545
2546 /**
2547  * To be documented.
2548  *
2549  * FIXME: To be fixed.
2550  */
2551 #ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
2552 EAPI void
2553 ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
2554 {
2555    Ecore_X_Window *winp;
2556
2557    winp = malloc(sizeof(Ecore_X_Window));
2558    if (winp)
2559      {
2560         *winp = win;
2561         ee->engine.x.win_extra = eina_list_append(ee->engine.x.win_extra, winp);
2562         ecore_x_input_multi_select(win);
2563         ecore_event_window_register(win, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
2564      }
2565 }
2566 #else
2567 EAPI void
2568 ecore_evas_software_x11_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
2569 {
2570 }
2571 #endif
2572
2573 /**
2574  * To be documented.
2575  *
2576  * FIXME: To be fixed.
2577  */
2578 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
2579 EAPI Ecore_Evas *
2580 ecore_evas_gl_x11_new(const char *disp_name, Ecore_X_Window parent,
2581                       int x, int y, int w, int h)
2582 {
2583 # ifdef HAVE_ECORE_X_XCB
2584    Ecore_Evas *ee = NULL;
2585 # else
2586    Ecore_Evas *ee;
2587    int rmethod;
2588
2589    rmethod = evas_render_method_lookup("gl_x11");
2590    if (!rmethod) return NULL;
2591    if (!ecore_x_init(disp_name)) return NULL;
2592    ee = calloc(1, sizeof(Ecore_Evas));
2593    if (!ee) return NULL;
2594
2595    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
2596
2597    _ecore_evas_x_init();
2598
2599    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
2600
2601    ee->driver = "opengl_x11";
2602    if (disp_name) ee->name = strdup(disp_name);
2603
2604    if (w < 1) w = 1;
2605    if (h < 1) h = 1;
2606    ee->x = x;
2607    ee->y = y;
2608    ee->w = w;
2609    ee->h = h;
2610
2611    ee->prop.max.w = 32767;
2612    ee->prop.max.h = 32767;
2613    ee->prop.layer = 4;
2614    ee->prop.request_pos = 0;
2615    ee->prop.sticky = 0;
2616    ee->engine.x.state.sticky = 0;
2617
2618    /* init evas here */
2619    ee->evas = evas_new();
2620    evas_data_attach_set(ee->evas, ee);
2621    evas_output_method_set(ee->evas, rmethod);
2622    evas_output_size_set(ee->evas, w, h);
2623    evas_output_viewport_set(ee->evas, 0, 0, w, h);
2624
2625    if (parent == 0) parent = DefaultRootWindow(ecore_x_display_get());
2626    ee->engine.x.win_root = parent;
2627
2628    ee->prop.window = _ecore_evas_x_gl_window_new(ee, ee->engine.x.win_root, x, y, w, h, 0);
2629
2630    if (getenv("DESKTOP_STARTUP_ID"))
2631      {
2632         ecore_x_netwm_startup_id_set(ee->prop.window,
2633                                      getenv("DESKTOP_STARTUP_ID"));
2634         /* NB: on linux this may simply empty the env as opposed to completely
2635          * unset it to being empty - unsure as solartis libc crashes looking
2636          * for the '=' char */
2637 //      putenv((char*)"DESKTOP_STARTUP_ID=");
2638      }
2639
2640    ecore_x_icccm_hints_set(ee->prop.window,
2641                            1 /* accepts_focus */,
2642                            ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2643                            0 /* icon_pixmap */,
2644                            0 /* icon_mask */,
2645                            0 /* icon_window */,
2646                            0 /* window_group */,
2647                            0 /* is_urgent */);
2648    
2649    ee->engine.func->fn_render = _ecore_evas_x_render;
2650    _ecore_evas_register(ee);
2651    ecore_x_input_multi_select(ee->prop.window);
2652    ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
2653 # endif /* HAVE_ECORE_X_XCB */
2654
2655    return ee;
2656 }
2657 #else
2658 EAPI Ecore_Evas *
2659 ecore_evas_gl_x11_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
2660                       int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
2661 {
2662    return NULL;
2663 }
2664 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
2665
2666 /**
2667  * To be documented.
2668  *
2669  * FIXME: To be fixed.
2670  */
2671 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
2672 EAPI Ecore_X_Window
2673 ecore_evas_gl_x11_window_get(const Ecore_Evas *ee)
2674 {
2675    return (Ecore_X_Window) ecore_evas_window_get(ee);
2676 }
2677 #else
2678 EAPI Ecore_X_Window
2679 ecore_evas_gl_x11_window_get(const Ecore_Evas *ee __UNUSED__)
2680 {
2681    return 0;
2682 }
2683 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
2684
2685 /**
2686  * To be documented.
2687  *
2688  * FIXME: To be fixed.
2689  */
2690 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
2691 EAPI void
2692 ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee, int on)
2693 {
2694    ee->engine.x.direct_resize = on;
2695 }
2696 #else
2697 EAPI void
2698 ecore_evas_gl_x11_direct_resize_set(Ecore_Evas *ee __UNUSED__, int on __UNUSED__)
2699 {
2700 }
2701 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
2702
2703 /**
2704  * To be documented.
2705  *
2706  * FIXME: To be fixed.
2707  */
2708 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
2709 EAPI int
2710 ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee)
2711 {
2712    return ee->engine.x.direct_resize;
2713 }
2714 #else
2715 EAPI int
2716 ecore_evas_gl_x11_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
2717 {
2718    return 0;
2719 }
2720 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
2721
2722 /**
2723  * To be documented.
2724  *
2725  * FIXME: To be fixed.
2726  */
2727 #ifdef BUILD_ECORE_EVAS_OPENGL_X11
2728 EAPI void
2729 ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
2730 {
2731    ecore_evas_software_x11_extra_event_window_add(ee, win);
2732 }
2733 #else
2734 EAPI void
2735 ecore_evas_gl_x11_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
2736 {
2737 }
2738 #endif /* ! BUILD_ECORE_EVAS_OPENGL_X11 */
2739
2740 /**
2741  * To be documented.
2742  *
2743  * FIXME: To be fixed.
2744  */
2745 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
2746 EAPI Ecore_Evas *
2747 ecore_evas_xrender_x11_new(const char *disp_name, Ecore_X_Window parent,
2748                       int x, int y, int w, int h)
2749 {
2750    Evas_Engine_Info_XRender_X11 *einfo;
2751    Ecore_Evas *ee;
2752    int rmethod;
2753
2754    rmethod = evas_render_method_lookup("xrender_x11");
2755    if (!rmethod) return NULL;
2756    if (!ecore_x_init(disp_name)) return NULL;
2757    ee = calloc(1, sizeof(Ecore_Evas));
2758    if (!ee) return NULL;
2759
2760    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
2761
2762    _ecore_evas_x_init();
2763
2764    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
2765
2766    ee->driver = "xrender_x11";
2767    if (disp_name) ee->name = strdup(disp_name);
2768
2769    if (w < 1) w = 1;
2770    if (h < 1) h = 1;
2771    ee->x = x;
2772    ee->y = y;
2773    ee->w = w;
2774    ee->h = h;
2775
2776    ee->prop.max.w = 32767;
2777    ee->prop.max.h = 32767;
2778    ee->prop.layer = 4;
2779    ee->prop.request_pos = 0;
2780    ee->prop.sticky = 0;
2781    ee->engine.x.state.sticky = 0;
2782
2783    /* init evas here */
2784    ee->evas = evas_new();
2785    evas_data_attach_set(ee->evas, ee);
2786    evas_output_method_set(ee->evas, rmethod);
2787    evas_output_size_set(ee->evas, w, h);
2788    evas_output_viewport_set(ee->evas, 0, 0, w, h);
2789
2790    ee->engine.x.win_root = parent;
2791    ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
2792    if (getenv("DESKTOP_STARTUP_ID"))
2793      {
2794         ecore_x_netwm_startup_id_set(ee->prop.window,
2795                                      getenv("DESKTOP_STARTUP_ID"));
2796         /* NB: on linux this may simply empty the env as opposed to completely
2797          * unset it to being empty - unsure as solartis libc crashes looking
2798          * for the '=' char */
2799 //      putenv((char*)"DESKTOP_STARTUP_ID=");
2800      }
2801    einfo = (Evas_Engine_Info_XRender_X11 *)evas_engine_info_get(ee->evas);
2802    if (einfo)
2803      {
2804 # ifdef BUILD_ECORE_EVAS_XRENDER_XCB
2805         xcb_screen_iterator_t iter;
2806         xcb_screen_t         *screen;
2807
2808         /* FIXME: this is inefficient as its a round trip */
2809         screen = ecore_x_default_screen_get();
2810         iter = xcb_setup_roots_iterator (xcb_get_setup (ecore_x_connection_get()));
2811         if (iter.rem > 1)
2812           {
2813              xcb_get_geometry_cookie_t cookie;
2814              xcb_get_geometry_reply_t *reply;
2815              Ecore_X_Window           *roots;
2816              int                       num;
2817              uint8_t                   i;
2818
2819              num = 0;
2820              cookie = xcb_get_geometry_unchecked(ecore_x_connection_get(), parent);
2821              roots = ecore_x_window_root_list(&num);
2822              if (roots)
2823                {
2824                   reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
2825
2826                   if (reply)
2827                     {
2828                        for (i = 0; i < num; xcb_screen_next (&iter), i++)
2829                          {
2830                             if (reply->root == roots[i])
2831                               {
2832                                  screen = iter.data;
2833                                  break;
2834                               }
2835                          }
2836                        free(reply);
2837                     }
2838                   free(roots);
2839                }
2840              else
2841                {
2842                   reply = xcb_get_geometry_reply(ecore_x_connection_get(), cookie, NULL);
2843                   if (reply) free(reply);
2844                }
2845           }
2846         einfo->info.backend = EVAS_ENGINE_INFO_XRENDER_BACKEND_XCB;
2847         einfo->info.connection = ecore_x_connection_get();
2848         einfo->info.screen = screen;
2849         einfo->info.visual = screen->root_visual;
2850 # elif BUILD_ECORE_EVAS_XRENDER_X11
2851         int screen;
2852
2853         /* FIXME: this is inefficient as its a round trip */
2854         screen = DefaultScreen(ecore_x_display_get());
2855         if (ScreenCount(ecore_x_display_get()) > 1)
2856           {
2857              Ecore_X_Window *roots;
2858              int num, i;
2859
2860              num = 0;
2861              roots = ecore_x_window_root_list(&num);
2862              if (roots)
2863                {
2864                   XWindowAttributes at;
2865
2866                   if (XGetWindowAttributes(ecore_x_display_get(),
2867                                            parent, &at))
2868                     {
2869                        for (i = 0; i < num; i++)
2870                          {
2871                             if (at.root == roots[i])
2872                               {
2873                                  screen = i;
2874                                  break;
2875                               }
2876                          }
2877                     }
2878                   free(roots);
2879                }
2880           }
2881         einfo->info.backend = EVAS_ENGINE_INFO_XRENDER_BACKEND_XLIB;
2882         einfo->info.connection = ecore_x_display_get();
2883         einfo->info.screen = NULL;
2884         einfo->info.visual = DefaultVisual(ecore_x_display_get(), screen);
2885 # endif /* BUILD_ECORE_EVAS_XRENDER_(XCB|X11) */
2886         einfo->info.drawable = ee->prop.window;
2887         evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
2888      }
2889
2890    ecore_x_icccm_hints_set(ee->prop.window,
2891                            1 /* accepts_focus */,
2892                            ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
2893                            0 /* icon_pixmap */,
2894                            0 /* icon_mask */,
2895                            0 /* icon_window */,
2896                            0 /* window_group */,
2897                            0 /* is_urgent */);
2898    
2899    ee->engine.func->fn_render = _ecore_evas_x_render;
2900    _ecore_evas_register(ee);
2901    ecore_x_input_multi_select(ee->prop.window);
2902    ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
2903    return ee;
2904 }
2905 #else
2906 EAPI Ecore_Evas *
2907 ecore_evas_xrender_x11_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
2908                            int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
2909 {
2910    return NULL;
2911 }
2912 #endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
2913
2914 /**
2915  * To be documented.
2916  *
2917  * FIXME: To be fixed.
2918  */
2919 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
2920 EAPI Ecore_X_Window
2921 ecore_evas_xrender_x11_window_get(const Ecore_Evas *ee)
2922 {
2923    return (Ecore_X_Window) ecore_evas_window_get(ee);
2924 }
2925 #else
2926 EAPI Ecore_X_Window
2927 ecore_evas_xrender_x11_window_get(const Ecore_Evas *ee __UNUSED__)
2928 {
2929    return 0;
2930 }
2931 #endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
2932
2933 /**
2934  * To be documented.
2935  *
2936  * FIXME: To be fixed.
2937  */
2938 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
2939 EAPI void
2940 ecore_evas_xrender_x11_direct_resize_set(Ecore_Evas *ee, int on)
2941 {
2942    ee->engine.x.direct_resize = on;
2943 }
2944 #else
2945 EAPI void
2946 ecore_evas_xrender_x11_direct_resize_set(Ecore_Evas *ee __UNUSED__, int on __UNUSED__)
2947 {
2948 }
2949 #endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
2950
2951 /**
2952  * To be documented.
2953  *
2954  * FIXME: To be fixed.
2955  */
2956 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
2957 EAPI int
2958 ecore_evas_xrender_x11_direct_resize_get(const Ecore_Evas *ee)
2959 {
2960    return ee->engine.x.direct_resize;
2961 }
2962 #else
2963 EAPI int
2964 ecore_evas_xrender_x11_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
2965 {
2966    return 0;
2967 }
2968 #endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
2969
2970 /**
2971  * To be documented.
2972  *
2973  * FIXME: To be fixed.
2974  */
2975 #if defined (BUILD_ECORE_EVAS_XRENDER_X11) || defined (BUILD_ECORE_EVAS_XRENDER_XCB)
2976 EAPI void
2977 ecore_evas_xrender_x11_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
2978 {
2979    ecore_evas_software_x11_extra_event_window_add(ee, win);
2980 }
2981 #else
2982 EAPI void
2983 ecore_evas_xrender_x11_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
2984 {
2985 }
2986 #endif /* ! BUILD_ECORE_EVAS_XRENDER_X11 && ! BUILD_ECORE_EVAS_XRENDER_XCB */
2987
2988 /**
2989  * To be documented.
2990  *
2991  * FIXME: To be fixed.
2992  */
2993 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
2994 EAPI Ecore_Evas *
2995 ecore_evas_software_x11_16_new(const char *disp_name, Ecore_X_Window parent,
2996                                int x, int y, int w, int h)
2997 {
2998    Evas_Engine_Info_Software_16_X11 *einfo;
2999    Ecore_Evas *ee;
3000    int rmethod;
3001    static int redraw_debug = -1;
3002
3003    rmethod = evas_render_method_lookup("software_16_x11");
3004    if (!rmethod) return NULL;
3005    if (!ecore_x_init(disp_name)) return NULL;
3006    ee = calloc(1, sizeof(Ecore_Evas));
3007    if (!ee) return NULL;
3008
3009    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
3010
3011    _ecore_evas_x_init();
3012
3013    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_x_engine_func;
3014
3015    ee->driver = "software_16_x11";
3016    if (disp_name) ee->name = strdup(disp_name);
3017
3018    if (w < 1) w = 1;
3019    if (h < 1) h = 1;
3020    ee->x = x;
3021    ee->y = y;
3022    ee->w = w;
3023    ee->h = h;
3024
3025    ee->prop.max.w = 32767;
3026    ee->prop.max.h = 32767;
3027    ee->prop.layer = 4;
3028    ee->prop.request_pos = 0;
3029    ee->prop.sticky = 0;
3030    ee->engine.x.state.sticky = 0;
3031
3032    /* init evas here */
3033    ee->evas = evas_new();
3034    evas_data_attach_set(ee->evas, ee);
3035    evas_output_method_set(ee->evas, rmethod);
3036    evas_output_size_set(ee->evas, w, h);
3037    evas_output_viewport_set(ee->evas, 0, 0, w, h);
3038
3039    ee->engine.x.win_root = parent;
3040    if (parent != 0)
3041      {
3042        /* FIXME: round trip in ecore_x_window_argb_get */
3043         if (ecore_x_window_argb_get(parent))
3044           {
3045              ee->prop.window = ecore_x_window_argb_new(parent, x, y, w, h);
3046           }
3047         else
3048           ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
3049      }
3050    else
3051      ee->prop.window = ecore_x_window_new(parent, x, y, w, h);
3052    if (getenv("DESKTOP_STARTUP_ID"))
3053      {
3054         ecore_x_netwm_startup_id_set(ee->prop.window,
3055                                      getenv("DESKTOP_STARTUP_ID"));
3056         /* NB: on linux this may simply empty the env as opposed to completely
3057          * unset it to being empty - unsure as solartis libc crashes looking
3058          * for the '=' char */
3059 //      putenv((char*)"DESKTOP_STARTUP_ID=");
3060      }
3061    einfo = (Evas_Engine_Info_Software_16_X11 *)evas_engine_info_get(ee->evas);
3062
3063    if (einfo)
3064      {
3065         if (ScreenCount(ecore_x_display_get()) > 1)
3066           {
3067              Ecore_X_Window *roots;
3068              int num, i;
3069
3070              num = 0;
3071              roots = ecore_x_window_root_list(&num);
3072              if (roots)
3073                {
3074                   XWindowAttributes at;
3075
3076                   if (XGetWindowAttributes(ecore_x_display_get(),
3077                                            parent, &at))
3078                     {
3079                        for (i = 0; i < num; i++)
3080                          {
3081                             if (at.root == roots[i])
3082                               break;
3083                          }
3084                     }
3085                   free(roots);
3086                }
3087           }
3088
3089         if (redraw_debug < 0)
3090           {
3091              if (getenv("REDRAW_DEBUG"))
3092                redraw_debug = atoi(getenv("REDRAW_DEBUG"));
3093              else
3094                redraw_debug = 0;
3095           }
3096         einfo->info.display  = ecore_x_display_get();
3097         einfo->info.drawable = ee->prop.window;
3098
3099         evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
3100      }
3101
3102    ecore_x_icccm_hints_set(ee->prop.window,
3103                            1 /* accepts_focus */,
3104                            ECORE_X_WINDOW_STATE_HINT_NORMAL /* initial_state */,
3105                            0 /* icon_pixmap */,
3106                            0 /* icon_mask */,
3107                            0 /* icon_window */,
3108                            0 /* window_group */,
3109                            0 /* is_urgent */);
3110    
3111    ee->engine.func->fn_render = _ecore_evas_x_render;
3112    _ecore_evas_register(ee);
3113    ecore_x_input_multi_select(ee->prop.window);
3114    ecore_event_window_register(ee->prop.window, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
3115    return ee;
3116 }
3117 #else
3118 EAPI Ecore_Evas *
3119 ecore_evas_software_x11_16_new(const char *disp_name __UNUSED__, Ecore_X_Window parent __UNUSED__,
3120                                int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__)
3121 {
3122    return NULL;
3123 }
3124 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
3125
3126 /**
3127  * To be documented.
3128  *
3129  * FIXME: To be fixed.
3130  */
3131 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
3132 EAPI Ecore_X_Window
3133 ecore_evas_software_x11_16_window_get(const Ecore_Evas *ee)
3134 {
3135    return (Ecore_X_Window) ecore_evas_window_get(ee);
3136 }
3137 #else
3138 EAPI Ecore_X_Window
3139 ecore_evas_software_x11_16_window_get(const Ecore_Evas *ee __UNUSED__)
3140 {
3141    return 0;
3142 }
3143 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
3144
3145 /**
3146  * To be documented.
3147  *
3148  * FIXME: To be fixed.
3149  */
3150 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
3151 EAPI void
3152 ecore_evas_software_x11_16_direct_resize_set(Ecore_Evas *ee, int on)
3153 {
3154    ee->engine.x.direct_resize = on;
3155    if (ee->prop.avoid_damage)
3156      {
3157         if (ee->engine.x.direct_resize)
3158           {
3159 /* turn this off for now
3160              ee->engine.x.using_bg_pixmap = 1;
3161              ecore_x_window_pixmap_set(ee->prop.window, ee->engine.x.pmap);
3162  */
3163           }
3164         else
3165           {
3166 /* turn this off too- bg pixmap is controlled by avoid damage directly
3167              ee->engine.x.using_bg_pixmap = 0;
3168              ecore_x_window_pixmap_set(ee->prop.window, 0);
3169              ecore_x_window_area_expose(ee->prop.window, 0, 0, ee->w, ee->h);
3170  */
3171           }
3172      }
3173 }
3174 #else
3175 EAPI void
3176 ecore_evas_software_x11_16_direct_resize_set(Ecore_Evas *ee __UNUSED__, int on __UNUSED__)
3177 {
3178 }
3179 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
3180
3181 /**
3182  * To be documented.
3183  *
3184  * FIXME: To be fixed.
3185  */
3186 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
3187 EAPI int
3188 ecore_evas_software_x11_16_direct_resize_get(const Ecore_Evas *ee)
3189 {
3190    return ee->engine.x.direct_resize;
3191 }
3192 #else
3193 EAPI int
3194 ecore_evas_software_x11_16_direct_resize_get(const Ecore_Evas *ee __UNUSED__)
3195 {
3196    return 0;
3197 }
3198 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */
3199
3200 /**
3201  * To be documented.
3202  *
3203  * FIXME: To be fixed.
3204  */
3205 #if BUILD_ECORE_EVAS_SOFTWARE_16_X11
3206 EAPI void
3207 ecore_evas_software_x11_16_extra_event_window_add(Ecore_Evas *ee, Ecore_X_Window win)
3208 {
3209    Ecore_X_Window *winp;
3210
3211    winp = malloc(sizeof(Ecore_X_Window));
3212    if (winp)
3213      {
3214         *winp = win;
3215         ee->engine.x.win_extra = eina_list_append(ee->engine.x.win_extra, winp);
3216         ecore_x_input_multi_select(win);
3217         ecore_event_window_register(win, ee, ee->evas, (Ecore_Event_Mouse_Move_Cb) _ecore_evas_mouse_move_process);
3218      }
3219 }
3220 #else
3221 EAPI void
3222 ecore_evas_software_x11_16_extra_event_window_add(Ecore_Evas *ee __UNUSED__, Ecore_X_Window win __UNUSED__)
3223 {
3224 }
3225 #endif /* ! BUILD_ECORE_EVAS_SOFTWARE_16_X11 */