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