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