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