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