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