1 #include "e.h"
2 
3 static Eina_List *handlers;
4 static Ecore_Timer *timer_post_screensaver_lock = NULL;
5 static Ecore_Timer *timer_post_screensaver_on = NULL;
6 static Ecore_Timer *timer_pointer_freeze = NULL;
7 
8 static void
_e_comp_canvas_cb_del()9 _e_comp_canvas_cb_del()
10 {
11    E_FREE_LIST(handlers, ecore_event_handler_del);
12    E_FREE_FUNC(timer_post_screensaver_lock, ecore_timer_del);
13    E_FREE_FUNC(timer_post_screensaver_on, ecore_timer_del);
14    E_FREE_FUNC(timer_pointer_freeze, ecore_timer_del);
15 }
16 
17 static void
_e_comp_canvas_event_compositor_resize_free(void * data EINA_UNUSED,void * event EINA_UNUSED)18 _e_comp_canvas_event_compositor_resize_free(void *data EINA_UNUSED, void *event EINA_UNUSED)
19 {
20    e_object_unref(E_OBJECT(e_comp));
21 }
22 
23 ///////////////////////////////////
24 
25 static void
_e_comp_canvas_cb_first_frame(void * data EINA_UNUSED,Evas * e,void * event_info EINA_UNUSED)26 _e_comp_canvas_cb_first_frame(void *data EINA_UNUSED, Evas *e, void *event_info EINA_UNUSED)
27 {
28    double now = ecore_time_get();
29 
30    switch (e_first_frame[0])
31      {
32       case 'A': abort();
33       case 'E':
34       case 'D': exit(101);
35       case 'T': fprintf(stderr, "Startup time: '%f' - '%f' = '%f'\n", now, e_first_frame_start_time, now - e_first_frame_start_time);
36          break;
37      }
38 
39    evas_event_callback_del_full(e, EVAS_CALLBACK_RENDER_POST, _e_comp_canvas_cb_first_frame, NULL);
40 }
41 
42 static void
_e_comp_canvas_render_post(void * data EINA_UNUSED,Evas * e EINA_UNUSED,void * event_info EINA_UNUSED)43 _e_comp_canvas_render_post(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
44 {
45    E_Comp_Config *conf = e_comp_config_get();
46    E_Client *ec;
47    //Evas_Event_Render_Post *ev = event_info;
48    //Eina_List *l;
49    //Eina_Rectangle *r;
50 
51    //if (ev)
52      //{
53         //EINA_LIST_FOREACH(ev->updated_area, l, r)
54           //INF("POST RENDER: %d,%d %dx%d", r->x, r->y, r->w, r->h);
55      //}
56 
57    e_comp->rendering = EINA_FALSE;
58 
59    EINA_LIST_FREE(e_comp->post_updates, ec)
60      {
61         //INF("POST %p", ec);
62         ec->on_post_updates = EINA_FALSE;
63         if (!e_object_is_del(E_OBJECT(ec)))
64           e_pixmap_image_clear(ec->pixmap, 1);
65         evas_object_smart_callback_call(ec->frame, "post_render", NULL);
66         UNREFD(ec, 111);
67         e_object_unref(E_OBJECT(ec));
68      }
69    if (conf->grab && e_comp->grabbed)
70      {
71         if (e_comp->grab_cb) e_comp->grab_cb();
72         e_comp->grabbed = 0;
73      }
74 }
75 
76 ///////////////////////////////////
77 
78 static void
_e_comp_canvas_cb_mouse_in(void * d EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info EINA_UNUSED)79 _e_comp_canvas_cb_mouse_in(void *d EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
80 {
81    E_Client *ec;
82 
83    e_comp_canvas_notidle();
84    if (e_client_action_get() || e_grabinput_mouse_win_get()) return;
85    ec = e_client_focused_get();
86    if (ec && (!ec->border_menu)) e_focus_event_mouse_out(ec);
87 }
88 
89 static void
_e_comp_canvas_cb_mouse_down(void * d EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)90 _e_comp_canvas_cb_mouse_down(void *d EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
91 {
92    e_comp_canvas_notidle();
93    if (e_client_action_get() || e_grabinput_mouse_win_get()) return;
94    e_bindings_mouse_down_evas_event_handle(E_BINDING_CONTEXT_COMPOSITOR, E_OBJECT(e_comp), event_info);
95 }
96 
97 static void
_e_comp_canvas_cb_mouse_up(void * d EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)98 _e_comp_canvas_cb_mouse_up(void *d EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
99 {
100    e_comp_canvas_notidle();
101    if (e_client_action_get() || e_grabinput_mouse_win_get()) return;
102    e_bindings_mouse_up_evas_event_handle(E_BINDING_CONTEXT_COMPOSITOR, E_OBJECT(e_comp), event_info);
103 }
104 
105 static void
_e_comp_canvas_cb_mouse_wheel(void * d EINA_UNUSED,Evas * e EINA_UNUSED,Evas_Object * obj EINA_UNUSED,void * event_info)106 _e_comp_canvas_cb_mouse_wheel(void *d EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
107 {
108    e_comp_canvas_notidle();
109    if (e_client_action_get() || e_grabinput_mouse_win_get()) return;
110    e_bindings_wheel_evas_event_handle(E_BINDING_CONTEXT_COMPOSITOR, E_OBJECT(e_comp), event_info);
111 }
112 
113 static Eina_Bool
_key_down(int ctx,Ecore_Event_Key * ev)114 _key_down(int ctx, Ecore_Event_Key *ev)
115 {
116    e_comp_canvas_notidle();
117    if (e_desklock_state_get() && (ctx == E_BINDING_CONTEXT_MANAGER))
118      {
119         E_Desklock_Interface *iface = e_desklock_interface_current_get();
120         if (iface && iface->key_down)
121           {
122 #ifdef HAVE_WAYLAND
123              if (e_comp->comp_type == E_PIXMAP_TYPE_WL)
124                e_comp_wl_key_down(ev, NULL);
125 #endif
126              return iface->key_down(ev);
127           }
128      }
129    if ((e_comp->comp_type == E_PIXMAP_TYPE_X) && (ev->event_window != e_comp->root))
130      {
131         E_Client *ec;
132 
133         ec = e_client_focused_get();
134         if (!ec) ec = e_client_action_get();
135         /* *block actions when no client is focused (probably something else did a grab here so we'll play nice)
136          * *block actions when menu is up
137          * *block actions when event (grab) window isn't comp window
138          * *other cases?
139          */
140         if ((!ec) || (ev->event_window != e_comp->ee_win)) return ECORE_CALLBACK_RENEW;
141      }
142    return ((!e_comp->screen) ||
143            (!e_comp->screen->key_down) || (!e_comp->screen->key_down(ev))) &&
144      !e_bindings_key_down_event_handle(ctx, E_OBJECT(e_comp), ev)
145 #ifdef HAVE_WAYLAND
146        && !e_comp_wl_key_down(ev, NULL)
147 #endif
148          ;
149 }
150 
151 static Eina_Bool
_e_comp_canvas_cb_key_down(void * data EINA_UNUSED,int ev_type EINA_UNUSED,Ecore_Event_Key * ev)152 _e_comp_canvas_cb_key_down(void *data EINA_UNUSED, int ev_type EINA_UNUSED, Ecore_Event_Key *ev)
153 {
154    return _key_down(E_BINDING_CONTEXT_COMPOSITOR, ev);
155 }
156 
157 static Eina_Bool
_e_comp_cb_key_down(void * data EINA_UNUSED,int ev_type EINA_UNUSED,Ecore_Event_Key * ev)158 _e_comp_cb_key_down(void *data EINA_UNUSED, int ev_type EINA_UNUSED, Ecore_Event_Key *ev)
159 {
160    return _key_down(E_BINDING_CONTEXT_MANAGER, ev);
161 }
162 
163 static Eina_Bool
_key_up(int ctx,Ecore_Event_Key * ev)164 _key_up(int ctx, Ecore_Event_Key *ev)
165 {
166    e_comp_canvas_notidle();
167    if (e_desklock_state_get() && (ctx == E_BINDING_CONTEXT_MANAGER))
168      {
169         E_Desklock_Interface *iface = e_desklock_interface_current_get();
170         if (iface && iface->key_up)
171           {
172 #ifdef HAVE_WAYLAND
173              if (e_comp->comp_type == E_PIXMAP_TYPE_WL)
174                e_comp_wl_key_up(ev, NULL);
175 #endif
176              return iface->key_up(ev);
177           }
178      }
179    if ((e_comp->comp_type == E_PIXMAP_TYPE_X) && (ev->event_window != e_comp->root)) return ECORE_CALLBACK_PASS_ON;
180    return ((!e_comp->screen) ||
181            (!e_comp->screen->key_up) || (!e_comp->screen->key_up(ev))) &&
182      !e_bindings_key_up_event_handle(ctx, E_OBJECT(e_comp), ev)
183 #ifdef HAVE_WAYLAND
184        && !e_comp_wl_key_up(ev, NULL)
185 #endif
186          ;
187 }
188 
189 static Eina_Bool
_e_comp_canvas_cb_key_up(void * data EINA_UNUSED,int ev_type EINA_UNUSED,Ecore_Event_Key * ev)190 _e_comp_canvas_cb_key_up(void *data EINA_UNUSED, int ev_type EINA_UNUSED, Ecore_Event_Key *ev)
191 {
192    return _key_up(E_BINDING_CONTEXT_COMPOSITOR, ev);
193 }
194 
195 static Eina_Bool
_e_comp_cb_key_up(void * data EINA_UNUSED,int ev_type EINA_UNUSED,Ecore_Event_Key * ev)196 _e_comp_cb_key_up(void *data EINA_UNUSED, int ev_type EINA_UNUSED, Ecore_Event_Key *ev)
197 {
198    return _key_up(E_BINDING_CONTEXT_MANAGER, ev);
199 }
200 
201 static Eina_Bool
_e_comp_cb_mouse_up(void * d EINA_UNUSED,int t EINA_UNUSED,Ecore_Event_Mouse_Button * ev)202 _e_comp_cb_mouse_up(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse_Button *ev)
203 {
204    if ((e_comp->comp_type == E_PIXMAP_TYPE_X) && (ev->event_window != e_comp->root))
205      return ECORE_CALLBACK_PASS_ON;
206    if (e_bindings_mouse_down_ecore_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(e_comp), ev))
207      return ECORE_CALLBACK_DONE;
208 
209 #ifdef HAVE_WAYLAND
210    return e_comp_wl_grab_client_mouse_button(ev);
211 #else
212    return ECORE_CALLBACK_RENEW;
213 #endif
214 }
215 
216 static Eina_Bool
_e_comp_cb_mouse_down(void * d EINA_UNUSED,int t EINA_UNUSED,Ecore_Event_Mouse_Button * ev)217 _e_comp_cb_mouse_down(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse_Button *ev)
218 {
219    if ((e_comp->comp_type == E_PIXMAP_TYPE_X) && (ev->event_window != e_comp->root))
220      return ECORE_CALLBACK_PASS_ON;
221    if (e_bindings_mouse_down_ecore_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(e_comp), ev))
222      return ECORE_CALLBACK_DONE;
223 #ifdef HAVE_WAYLAND
224    return e_comp_wl_grab_client_mouse_button(ev);
225 #else
226    return ECORE_CALLBACK_RENEW;
227 #endif
228 }
229 
230 static Eina_Bool
_e_comp_cb_mouse_wheel(void * d EINA_UNUSED,int t EINA_UNUSED,Ecore_Event_Mouse_Wheel * ev)231 _e_comp_cb_mouse_wheel(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse_Wheel *ev)
232 {
233    if ((e_comp->comp_type == E_PIXMAP_TYPE_X) && (ev->event_window != e_comp->root))
234      return ECORE_CALLBACK_PASS_ON;
235    return !e_bindings_wheel_ecore_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(e_comp), ev);
236 }
237 
238 #ifdef HAVE_WAYLAND
239 static Eina_Bool
_e_comp_cb_mouse_move(void * d EINA_UNUSED,int t EINA_UNUSED,Ecore_Event_Mouse_Move * ev)240 _e_comp_cb_mouse_move(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse_Move *ev)
241 {
242    static int x = -9999, y = -9999;
243 
244    if (e_comp->comp_type != E_PIXMAP_TYPE_WL) return ECORE_CALLBACK_RENEW;
245    if (x == -9999)
246      x = ev->x, y = ev->y;
247    if ((x == ev->x) && (y == ev->y)) return ECORE_CALLBACK_RENEW;
248    if (e_client_focused_get() && (!e_comp_util_mouse_grabbed()))
249      {
250         if ((!e_comp->screen) || (!e_comp->screen->relative_motion))
251           {
252              e_comp_wl_extension_relative_motion_event(ecore_time_unix_get() * 1000ULL,
253                ev->x - x, ev->y - y, 0, 0);
254           }
255         x = ev->x, y = ev->y;
256         if (e_comp_wl_extension_pointer_constraints_update(e_client_focused_get(), ev->x, ev->y))
257           return ECORE_CALLBACK_CANCEL;
258      }
259    x = ev->x, y = ev->y;
260    return e_comp_wl_grab_client_mouse_move(ev);
261 }
262 #endif
263 
264 ////////////////////////////////////
265 
266 static Eina_Bool
_e_comp_cb_zone_change()267 _e_comp_cb_zone_change()
268 {
269    e_comp_canvas_update();
270    return ECORE_CALLBACK_PASS_ON;
271 }
272 
273 ////////////////////////////////////
274 
275 static Eina_Bool
_e_comp_cb_screensaver_active_delay(void * data EINA_UNUSED)276 _e_comp_cb_screensaver_active_delay(void *data EINA_UNUSED)
277 {
278    ecore_animator_frametime_set(10.0);
279    if (!e_comp->nocomp)
280      ecore_evas_manual_render_set(e_comp->ee, EINA_TRUE);
281    timer_post_screensaver_on = NULL;
282    return ECORE_CALLBACK_CANCEL;
283 }
284 
285 static void
_e_comp_canvas_screensaver_active(void * d EINA_UNUSED,Evas_Object * obj EINA_UNUSED,const char * sig EINA_UNUSED,const char * src EINA_UNUSED)286 _e_comp_canvas_screensaver_active(void *d EINA_UNUSED, Evas_Object *obj EINA_UNUSED, const char *sig EINA_UNUSED, const char *src EINA_UNUSED)
287 {
288    if (timer_post_screensaver_on) return;
289    /* thawed in _e_comp_screensaver_off() */
290    timer_post_screensaver_on = ecore_timer_loop_add
291      (1.0, _e_comp_cb_screensaver_active_delay, NULL);
292 }
293 
294 static Eina_Bool
_e_comp_cb_timer_post_screensaver_lock(void * data EINA_UNUSED)295 _e_comp_cb_timer_post_screensaver_lock(void *data EINA_UNUSED)
296 {
297    // XXX: the below should instantly show desklock and have no transition
298    // or animation
299    e_desklock_show_autolocked();
300    timer_post_screensaver_lock = NULL;
301    return ECORE_CALLBACK_CANCEL;
302 }
303 
304 static Eina_Bool
_e_comp_cb_screensaver_ponter_freeze_cb(void * data EINA_UNUSED)305 _e_comp_cb_screensaver_ponter_freeze_cb(void *data EINA_UNUSED)
306 {
307    e_pointers_freeze_set(EINA_TRUE);
308    timer_pointer_freeze = NULL;
309    return EINA_FALSE;
310 }
311 
312 static Eina_Bool
_e_comp_cb_screensaver_on()313 _e_comp_cb_screensaver_on()
314 {
315    // XXX: this is not quite right. this here should be called after e_comp.c
316    // and freinds have emitted "e,state,screensaver,on" AND gotten a signal
317    // reply from the theme to say it's done with this animation before
318    // doing the below
319    if (e_config->desklock_autolock_screensaver)
320      {
321         E_FREE_FUNC(timer_post_screensaver_lock, ecore_timer_del);
322         if (e_config->desklock_post_screensaver_time <= 1.0)
323           e_desklock_show_autolocked();
324         else
325           timer_post_screensaver_lock = ecore_timer_loop_add
326               (e_config->desklock_post_screensaver_time,
327               _e_comp_cb_timer_post_screensaver_lock, NULL);
328      }
329    if (timer_pointer_freeze) ecore_timer_del(timer_pointer_freeze);
330    timer_pointer_freeze = ecore_timer_add
331      (10.0, _e_comp_cb_screensaver_ponter_freeze_cb, NULL);
332    return ECORE_CALLBACK_PASS_ON;
333 }
334 
335 static Eina_Bool
_e_comp_cb_screensaver_off()336 _e_comp_cb_screensaver_off()
337 {
338    E_FREE_FUNC(timer_post_screensaver_lock, ecore_timer_del);
339    E_FREE_FUNC(timer_post_screensaver_on, ecore_timer_del);
340    e_pointers_freeze_set(EINA_FALSE);
341    if (timer_pointer_freeze)
342      {
343         ecore_timer_del(timer_pointer_freeze);
344         timer_pointer_freeze = NULL;
345      }
346    return ECORE_CALLBACK_PASS_ON;
347 }
348 ////////////////////////////////////
349 
350 static int
_e_comp_canvas_cb_zone_sort(const void * data1,const void * data2)351 _e_comp_canvas_cb_zone_sort(const void *data1, const void *data2)
352 {
353    const E_Zone *z1 = data1, *z2 = data2;
354 
355    return z1->num - z2->num;
356 }
357 
358 static void
_e_comp_canvas_prerender(void * data EINA_UNUSED,Evas * e EINA_UNUSED,void * event_info EINA_UNUSED)359 _e_comp_canvas_prerender(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *event_info EINA_UNUSED)
360 {
361    E_Comp_Cb cb;
362    Eina_List *l;
363    E_Comp_Config *conf = e_comp_config_get();
364 
365    e_comp->rendering = EINA_TRUE;
366 
367    if (conf->grab && (!e_comp->grabbed))
368      {
369         if (e_comp->grab_cb) e_comp->grab_cb();
370         e_comp->grabbed = 1;
371      }
372 
373    EINA_LIST_FOREACH(e_comp->pre_render_cbs, l, cb)
374      cb();
375 }
376 
377 E_API Eina_Bool
e_comp_canvas_init(int w,int h)378 e_comp_canvas_init(int w, int h)
379 {
380    Evas_Object *o;
381    Eina_List *screens;
382    char *bsize;
383 
384    e_comp->w = w;
385    e_comp->h = h;
386    bsize = getenv("E_COMP_SIZE");
387    if (bsize)
388      {
389         int ew = w, eh = h;
390 
391         if (sscanf(bsize, "%dx%d", &ew, &eh) == 2)
392           {
393              if ((w > 0) && (h > 0))
394                e_comp->w = ew, e_comp->h = eh;
395           }
396      }
397 
398    e_comp->evas = ecore_evas_get(e_comp->ee);
399 
400    if (e_first_frame)
401      evas_event_callback_add(e_comp->evas, EVAS_CALLBACK_RENDER_POST, _e_comp_canvas_cb_first_frame, NULL);
402    o = evas_object_rectangle_add(e_comp->evas);
403    e_comp->canvas->resize_object = o;
404    evas_object_layer_set(o, E_LAYER_BOTTOM);
405    evas_object_move(o, 0, 0);
406    evas_object_resize(o, e_comp->w, e_comp->h);
407    evas_object_color_set(o, 0, 0, 0, 255);
408    evas_object_name_set(o, "comp->canvas->resize_object");
409    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, (Evas_Object_Event_Cb)_e_comp_canvas_cb_mouse_down, NULL);
410    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, (Evas_Object_Event_Cb)_e_comp_canvas_cb_mouse_up, NULL);
411    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_IN, (Evas_Object_Event_Cb)_e_comp_canvas_cb_mouse_in, NULL);
412    evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_WHEEL, (Evas_Object_Event_Cb)_e_comp_canvas_cb_mouse_wheel, NULL);
413    evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _e_comp_canvas_cb_del, NULL);
414    evas_object_show(o);
415 
416    ecore_evas_name_class_set(e_comp->ee, "E", "Comp_EE");
417    //   ecore_evas_manual_render_set(e_comp->ee, conf->lock_fps);
418    ecore_evas_show(e_comp->ee);
419 
420    evas_event_callback_add(e_comp->evas, EVAS_CALLBACK_RENDER_FLUSH_POST, _e_comp_canvas_render_post, NULL);
421 
422    e_comp->ee_win = ecore_evas_window_get(e_comp->ee);
423 
424    screens = (Eina_List *)e_xinerama_screens_get();
425    if (screens)
426      {
427         E_Screen *scr;
428         Eina_List *l;
429 
430         EINA_LIST_FOREACH(screens, l, scr)
431           {
432              E_Zone *zone = e_zone_new(scr->screen, scr->escreen,
433                                        scr->x, scr->y, scr->w, scr->h);
434              if (scr->id) zone->randr2_id = strdup(scr->id);
435              e_desk_window_profile_update(zone);
436           }
437      }
438    else
439      e_zone_new(0, 0, 0, 0, e_comp->w, e_comp->h);
440    E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_MOVE_RESIZE, _e_comp_cb_zone_change, NULL);
441    E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_ADD, _e_comp_cb_zone_change, NULL);
442    E_LIST_HANDLER_APPEND(handlers, E_EVENT_ZONE_DEL, _e_comp_cb_zone_change, NULL);
443    E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_KEY_DOWN, _e_comp_canvas_cb_key_down, NULL);
444    E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_KEY_UP, _e_comp_canvas_cb_key_up, NULL);
445    E_LIST_HANDLER_APPEND(handlers, E_EVENT_SCREENSAVER_ON, _e_comp_cb_screensaver_on, NULL);
446    E_LIST_HANDLER_APPEND(handlers, E_EVENT_SCREENSAVER_OFF, _e_comp_cb_screensaver_off, NULL);
447 
448    evas_event_callback_add(e_comp->evas, EVAS_CALLBACK_RENDER_PRE, _e_comp_canvas_prerender, NULL);
449    ecore_evas_resize(e_comp->ee, w, h);
450    if ((!after_restart) || (!e_comp_x))
451      ecore_evas_pointer_warp(e_comp->ee, e_comp->w / 2, e_comp->h / 2);
452 
453 #ifdef HAVE_WAYLAND
454    if (e_comp->comp_type == E_PIXMAP_TYPE_WL)
455      e_comp_wl_notidle();
456 #endif
457    return EINA_TRUE;
458 }
459 
460 EINTERN void
e_comp_canvas_clear(void)461 e_comp_canvas_clear(void)
462 {
463    evas_event_freeze(e_comp->evas);
464    edje_freeze();
465 
466    E_FREE_FUNC(e_comp->canvas->fps_fg, evas_object_del);
467    E_FREE_FUNC(e_comp->canvas->fps_bg, evas_object_del);
468    E_FREE_FUNC(e_comp->autoclose.rect, evas_object_del);
469    E_FREE_FUNC(e_comp->shape_job, ecore_job_del);
470    E_FREE_FUNC(e_comp->pointer, e_object_del);
471 }
472 
473 //////////////////////////////////////////////
474 
475 E_API void
e_comp_canvas_resize(int w,int h)476 e_comp_canvas_resize(int w, int h)
477 {
478    e_comp->w = w;
479    e_comp->h = h;
480    ecore_evas_resize(e_comp->ee, w, h);
481 }
482 
483 E_API void
e_comp_all_freeze(void)484 e_comp_all_freeze(void)
485 {
486    evas_event_freeze(e_comp->evas);
487 }
488 
489 E_API void
e_comp_all_thaw(void)490 e_comp_all_thaw(void)
491 {
492    evas_event_thaw(e_comp->evas);
493 }
494 
495 E_API E_Zone *
e_comp_zone_xy_get(Evas_Coord x,Evas_Coord y)496 e_comp_zone_xy_get(Evas_Coord x, Evas_Coord y)
497 {
498    const Eina_List *l;
499    E_Zone *zone;
500 
501    EINA_LIST_FOREACH(e_comp->zones, l, zone)
502      if (E_INSIDE(x, y, zone->x, zone->y, zone->w, zone->h)) return zone;
503    return NULL;
504 }
505 
506 E_API E_Zone *
e_comp_zone_number_get(int num)507 e_comp_zone_number_get(int num)
508 {
509    Eina_List *l = NULL;
510    E_Zone *zone = NULL;
511 
512    EINA_LIST_FOREACH(e_comp->zones, l, zone)
513      {
514         if ((int)zone->num == num) return zone;
515      }
516    return NULL;
517 }
518 
519 E_API E_Zone *
e_comp_zone_id_get(int id)520 e_comp_zone_id_get(int id)
521 {
522    Eina_List *l = NULL;
523    E_Zone *zone = NULL;
524 
525    EINA_LIST_FOREACH(e_comp->zones, l, zone)
526      {
527         if (zone->id == id) return zone;
528      }
529    return NULL;
530 }
531 
532 E_API E_Desk *
e_comp_desk_window_profile_get(const char * profile)533 e_comp_desk_window_profile_get(const char *profile)
534 {
535    Eina_List *l = NULL;
536    E_Zone *zone = NULL;
537    int x, y;
538 
539    EINA_SAFETY_ON_NULL_RETURN_VAL(profile, NULL);
540 
541    EINA_LIST_FOREACH(e_comp->zones, l, zone)
542      {
543         for (x = 0; x < zone->desk_x_count; x++)
544           {
545              for (y = 0; y < zone->desk_y_count; y++)
546                {
547                   E_Desk *desk = e_desk_at_xy_get(zone, x, y);
548                   if (desk)
549                     {
550                        if (e_object_is_del(E_OBJECT(desk))) continue;
551                        if (!e_util_strcmp(desk->window_profile, profile))
552                          return desk;
553                     }
554                }
555           }
556      }
557 
558    return NULL;
559 }
560 
561 E_API void
e_comp_canvas_zone_restarted(E_Zone * zone)562 e_comp_canvas_zone_restarted(E_Zone *zone)
563 {
564    if (edje_object_data_get(zone->over, "restarted"))
565      {
566         edje_object_signal_emit(zone->over, "e,state,sys,restarted,show", "e");
567      }
568 }
569 
570 E_API void
e_comp_canvas_zone_update(E_Zone * zone)571 e_comp_canvas_zone_update(E_Zone *zone)
572 {
573    Evas_Object *o;
574 
575    if (zone->over && zone->base)
576      {
577         e_theme_edje_object_set(zone->base, "base/theme/comp",
578                                 "e/comp/screen/base/default");
579         edje_object_part_swallow(zone->base, "e.swallow.background",
580                                  zone->transition_object ?: zone->bg_object);
581         e_theme_edje_object_set(zone->over, "base/theme/comp",
582                                 "e/comp/screen/overlay/default");
583         return;
584      }
585    E_FREE_FUNC(zone->base, evas_object_del);
586    E_FREE_FUNC(zone->over, evas_object_del);
587    zone->base = o = edje_object_add(e_comp->evas);
588    evas_object_repeat_events_set(o, 1);
589    evas_object_name_set(zone->base, "zone->base");
590    e_theme_edje_object_set(o, "base/theme/comp", "e/comp/screen/base/default");
591    edje_object_part_swallow(zone->base, "e.swallow.background", zone->transition_object ?: zone->bg_object);
592    evas_object_move(o, zone->x, zone->y);
593    evas_object_resize(o, zone->w, zone->h);
594    evas_object_layer_set(o, E_LAYER_BG);
595    evas_object_show(o);
596 
597    zone->over = o = edje_object_add(e_comp->evas);
598    edje_object_signal_callback_add(o, "e,state,screensaver,active", "e", _e_comp_canvas_screensaver_active, NULL);
599    evas_object_layer_set(o, E_LAYER_MAX);
600    evas_object_raise(o);
601    evas_object_name_set(zone->over, "zone->over");
602    evas_object_pass_events_set(o, 1);
603    e_theme_edje_object_set(o, "base/theme/comp", "e/comp/screen/overlay/default");
604    evas_object_move(o, zone->x, zone->y);
605    evas_object_resize(o, zone->w, zone->h);
606    evas_object_raise(o);
607    evas_object_show(o);
608    if (starting && after_restart &&
609        (edje_object_data_get(zone->over, "restarted")))
610      {
611         edje_object_signal_emit(zone->over, "e,state,sys,restarted", "e");
612         edje_object_message_signal_process(zone->over);
613      }
614 }
615 
616 E_API void
e_comp_canvas_update(void)617 e_comp_canvas_update(void)
618 {
619    Eina_List *l, *screens, *zones = NULL, *ll;
620    E_Zone *zone;
621    E_Screen *scr;
622    Eina_Bool changed = EINA_FALSE;
623 
624    screens = (Eina_List *)e_xinerama_screens_get();
625 
626    if (screens)
627      {
628         zones = e_comp->zones;
629         e_comp->zones = NULL;
630         printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
631         EINA_LIST_FOREACH(screens, l, scr)
632           {
633              zone = NULL;
634 
635              printf("@ match screens %p[%i] = %i %i %ix%i -- %i\n",
636                     scr, scr->escreen, scr->x, scr->y, scr->w, scr->h, scr->escreen);
637              EINA_LIST_FOREACH(zones, ll, zone)
638                {
639                   if (zone->id == scr->escreen) break;
640                   zone = NULL;
641                }
642              printf("@ matches existing zone %p\n", zone);
643              if (zone)
644                {
645                   printf("   move resize %i %i %ix%i -> %i %i %ix%i\n",
646                          zone->x, zone->y, zone->w, zone->h,
647                          scr->x, scr->y, scr->w, scr->h);
648                   changed |= e_zone_move_resize(zone, scr->x, scr->y, scr->w, scr->h);
649                   if (changed)
650                     printf("@@@ FOUND ZONE %i %i [%p]\n", zone->num, zone->id, zone);
651                   zones = eina_list_remove(zones, zone);
652                   e_comp->zones = eina_list_append(e_comp->zones, zone);
653                   zone->num = scr->screen;
654                   free(zone->randr2_id);
655                   zone->randr2_id = NULL;
656                   if (scr->id) zone->randr2_id = strdup(scr->id);
657                   e_desk_window_profile_update(zone);
658                }
659              else
660                {
661                   zone = e_zone_new(scr->screen, scr->escreen,
662                                     scr->x, scr->y, scr->w, scr->h);
663                   if (scr->id) zone->randr2_id = strdup(scr->id);
664                   e_desk_window_profile_update(zone);
665                   printf("@@@ NEW ZONE = %p\n", zone);
666                   changed = EINA_TRUE;
667                }
668              if (changed)
669                printf("@@@ SCREENS: %i %i | %i %i %ix%i\n",
670                       scr->screen, scr->escreen, scr->x, scr->y, scr->w, scr->h);
671           }
672         e_comp->zones = eina_list_sort(e_comp->zones, 0, _e_comp_canvas_cb_zone_sort);
673         if (zones)
674           {
675              E_Zone *spare_zone;
676 
677              printf("@zones have been deleted....\n");
678              changed = EINA_TRUE;
679              spare_zone = eina_list_data_get(e_comp->zones);
680 
681              EINA_LIST_FREE(zones, zone)
682                {
683                   E_Client *ec;
684 
685                   printf("reassign all clients from deleted zone %p\n", zone);
686                   E_CLIENT_FOREACH(ec)
687                     {
688                        if (ec->zone == zone)
689                          {
690                             if (spare_zone)
691                               e_client_zone_set(ec, spare_zone);
692                             else
693                               printf("EEEK! should not be here - but no\n"
694                                      "spare zones exist to move this\n"
695                                      "window to!!! help!\n");
696                          }
697                     }
698                   e_object_del(E_OBJECT(zone));
699                }
700           }
701         if (changed) e_shelf_config_update();
702      }
703    else
704      {
705         E_Zone *z;
706 
707         z = e_comp_zone_number_get(0);
708         if (z)
709           {
710              changed |= e_zone_move_resize(z, 0, 0, e_comp->w, e_comp->h);
711              if (changed) e_shelf_zone_move_resize_handle(z);
712           }
713      }
714 
715    e_comp_clients_rescale();
716    if (!changed) return;
717    if (!starting)
718      {
719         e_object_ref(E_OBJECT(e_comp));
720         ecore_event_add(E_EVENT_COMPOSITOR_UPDATE, NULL, _e_comp_canvas_event_compositor_resize_free, NULL);
721      }
722 
723    EINA_LIST_FOREACH(e_comp->zones, l, zone)
724      {
725         E_FREE_FUNC(zone->base, evas_object_del);
726         E_FREE_FUNC(zone->over, evas_object_del);
727         if (zone->bloff)
728           {
729              if (!e_comp_config_get()->nofade)
730                {
731                   if (e_backlight_mode_get(zone) != E_BACKLIGHT_MODE_NORMAL)
732                     e_backlight_mode_set(zone, E_BACKLIGHT_MODE_NORMAL);
733                   e_backlight_level_set(zone, e_config->backlight.normal, -1.0);
734                }
735           }
736         e_comp_canvas_zone_update(zone);
737         if (!starting)
738           e_bindings_edge_reset();
739      }
740    evas_object_resize(e_comp->canvas->resize_object, e_comp->w, e_comp->h);
741 }
742 
743 E_API void
e_comp_canvas_fake_layers_init(void)744 e_comp_canvas_fake_layers_init(void)
745 {
746    unsigned int layer;
747 
748    /* init layers */
749    for (layer = e_comp_canvas_layer_map(E_LAYER_CLIENT_DESKTOP); layer <= e_comp_canvas_layer_map(E_LAYER_CLIENT_PRIO); layer++)
750      {
751         Evas_Object *o2;
752 
753         o2 = e_comp->layers[layer].obj = evas_object_rectangle_add(e_comp->evas);
754         evas_object_layer_set(o2, e_comp_canvas_layer_map_to(layer));
755         evas_object_name_set(o2, "layer_obj");
756      }
757 }
758 
759 E_API void
e_comp_canvas_fps_toggle(void)760 e_comp_canvas_fps_toggle(void)
761 {
762    E_Comp_Config *conf = e_comp_config_get();
763 
764    conf->fps_show = !conf->fps_show;
765    e_comp_internal_save();
766    e_comp_render_queue();
767 }
768 
769 E_API E_Layer
e_comp_canvas_layer_map_to(unsigned int layer)770 e_comp_canvas_layer_map_to(unsigned int layer)
771 {
772    switch (layer)
773      {
774       case 0: return E_LAYER_BOTTOM;
775       case 1: return E_LAYER_BG;
776       case 2: return E_LAYER_DESKTOP;
777       case 3: return E_LAYER_DESKTOP_TOP;
778       case 4: return E_LAYER_CLIENT_DESKTOP;
779       case 5: return E_LAYER_CLIENT_BELOW;
780       case 6: return E_LAYER_CLIENT_NORMAL;
781       case 7: return E_LAYER_CLIENT_ABOVE;
782       case 8: return E_LAYER_CLIENT_EDGE;
783       case 9: return E_LAYER_CLIENT_FULLSCREEN;
784       case 10: return E_LAYER_CLIENT_EDGE_FULLSCREEN;
785       case 11: return E_LAYER_CLIENT_POPUP;
786       case 12: return E_LAYER_CLIENT_TOP;
787       case 13: return E_LAYER_CLIENT_DRAG;
788       case 14: return E_LAYER_CLIENT_PRIO;
789       case 15: return E_LAYER_POPUP;
790       case 16: return E_LAYER_MENU;
791       case 17: return E_LAYER_DESKLOCK;
792       case 18: return E_LAYER_MAX;
793       default: break;
794      }
795    return -INT_MAX;
796 }
797 
798 E_API unsigned int
e_comp_canvas_layer_map(E_Layer layer)799 e_comp_canvas_layer_map(E_Layer layer)
800 {
801    switch (layer)
802      {
803       case E_LAYER_BOTTOM: return 0;
804       case E_LAYER_BG: return 1;
805       case E_LAYER_DESKTOP: return 2;
806       case E_LAYER_DESKTOP_TOP: return 3;
807       case E_LAYER_CLIENT_DESKTOP: return 4;
808       case E_LAYER_CLIENT_BELOW: return 5;
809       case E_LAYER_CLIENT_NORMAL: return 6;
810       case E_LAYER_CLIENT_ABOVE: return 7;
811       case E_LAYER_CLIENT_EDGE: return 8;
812       case E_LAYER_CLIENT_FULLSCREEN: return 9;
813       case E_LAYER_CLIENT_EDGE_FULLSCREEN: return 10;
814       case E_LAYER_CLIENT_POPUP: return 11;
815       case E_LAYER_CLIENT_TOP: return 12;
816       case E_LAYER_CLIENT_DRAG: return 13;
817       case E_LAYER_CLIENT_PRIO: return 14;
818       case E_LAYER_POPUP: return 15;
819       case E_LAYER_MENU: return 16;
820       case E_LAYER_DESKLOCK: return 17;
821       case E_LAYER_MAX: return 18;
822       default: break;
823      }
824    return 9999;
825 }
826 
827 E_API unsigned int
e_comp_canvas_client_layer_map(E_Layer layer)828 e_comp_canvas_client_layer_map(E_Layer layer)
829 {
830    switch (layer)
831      {
832       case E_LAYER_CLIENT_DESKTOP: return 0;
833       case E_LAYER_CLIENT_BELOW: return 1;
834       case E_LAYER_CLIENT_NORMAL: return 2;
835       case E_LAYER_CLIENT_ABOVE: return 3;
836       case E_LAYER_CLIENT_EDGE: return 4;
837       case E_LAYER_CLIENT_FULLSCREEN: return 5;
838       case E_LAYER_CLIENT_EDGE_FULLSCREEN: return 6;
839       case E_LAYER_CLIENT_POPUP: return 7;
840       case E_LAYER_CLIENT_TOP: return 8;
841       case E_LAYER_CLIENT_DRAG: return 9;
842       case E_LAYER_CLIENT_PRIO: return 10;
843       default: break;
844      }
845    return 9999;
846 }
847 
848 E_API E_Layer
e_comp_canvas_client_layer_map_nearest(int layer)849 e_comp_canvas_client_layer_map_nearest(int layer)
850 {
851 #define LAYER_MAP(X) \
852    if (layer <= X) return X
853 
854    LAYER_MAP(E_LAYER_CLIENT_DESKTOP);
855    LAYER_MAP(E_LAYER_CLIENT_BELOW);
856    LAYER_MAP(E_LAYER_CLIENT_NORMAL);
857    LAYER_MAP(E_LAYER_CLIENT_ABOVE);
858    LAYER_MAP(E_LAYER_CLIENT_EDGE);
859    LAYER_MAP(E_LAYER_CLIENT_FULLSCREEN);
860    LAYER_MAP(E_LAYER_CLIENT_EDGE_FULLSCREEN);
861    LAYER_MAP(E_LAYER_CLIENT_POPUP);
862    LAYER_MAP(E_LAYER_CLIENT_TOP);
863    LAYER_MAP(E_LAYER_CLIENT_DRAG);
864    return E_LAYER_CLIENT_PRIO;
865 }
866 
867 E_API void
e_comp_canvas_keys_grab(void)868 e_comp_canvas_keys_grab(void)
869 {
870    if (e_comp->comp_type == E_PIXMAP_TYPE_X)
871      e_bindings_key_grab(E_BINDING_CONTEXT_ANY, e_comp->root);
872 }
873 
874 E_API void
e_comp_canvas_keys_ungrab(void)875 e_comp_canvas_keys_ungrab(void)
876 {
877    if (e_comp->comp_type == E_PIXMAP_TYPE_X)
878      e_bindings_key_ungrab(E_BINDING_CONTEXT_ANY, e_comp->root);
879 }
880 
881 E_API void
e_comp_canvas_feed_mouse_up(unsigned int activate_time)882 e_comp_canvas_feed_mouse_up(unsigned int activate_time)
883 {
884    int button_mask, i;
885 
886    button_mask = evas_pointer_button_down_mask_get(e_comp->evas);
887    for (i = 0; i < 32; i++)
888      {
889        if ((button_mask & (1 << i)))
890          evas_event_feed_mouse_up(e_comp->evas, i + 1, EVAS_BUTTON_NONE, activate_time, NULL);
891      }
892 }
893 
894 E_API void
e_comp_canvas_notidle(void)895 e_comp_canvas_notidle(void)
896 {
897 #ifdef HAVE_WAYLAND
898    if (e_comp->comp_type == E_PIXMAP_TYPE_WL) e_comp_wl_notidle();
899 #endif
900 }
901 
902 E_API Evas_Object *
e_comp_canvas_event_grabber_add(void)903 e_comp_canvas_event_grabber_add(void)
904 {
905    E_Zone *zone;
906    Eina_List *l;
907    Evas_Object *o;
908 
909    o = evas_object_event_grabber_add(e_comp->evas);
910    EINA_LIST_FOREACH(e_comp->zones, l, zone)
911      {
912 #define EDGE_ADD(E) \
913         if (zone->E) \
914           evas_object_smart_member_add(zone->E, o)
915 
916         EDGE_ADD(edge.top);
917         EDGE_ADD(edge.right);
918         EDGE_ADD(edge.bottom);
919         EDGE_ADD(edge.left);
920 
921         EDGE_ADD(corner.left_top);
922         EDGE_ADD(corner.right_top);
923         EDGE_ADD(corner.top_left);
924         EDGE_ADD(corner.top_right);
925         EDGE_ADD(corner.left_bottom);
926         EDGE_ADD(corner.right_bottom);
927         EDGE_ADD(corner.bottom_left);
928         EDGE_ADD(corner.bottom_right);
929      }
930    return o;
931 }
932 
933 EINTERN void
e_comp_canvas_intercept(void)934 e_comp_canvas_intercept(void)
935 {
936    ecore_event_init();
937    E_LIST_HANDLER_APPEND_PRE(handlers, ECORE_EVENT_MOUSE_BUTTON_DOWN, _e_comp_cb_mouse_down, NULL);
938    E_LIST_HANDLER_APPEND_PRE(handlers, ECORE_EVENT_MOUSE_BUTTON_UP, _e_comp_cb_mouse_up, NULL);
939    E_LIST_HANDLER_APPEND_PRE(handlers, ECORE_EVENT_MOUSE_WHEEL, _e_comp_cb_mouse_wheel, NULL);
940 #ifdef HAVE_WAYLAND
941    E_LIST_HANDLER_APPEND_PRE(handlers, ECORE_EVENT_MOUSE_MOVE, _e_comp_cb_mouse_move, NULL);
942 #endif
943    E_LIST_HANDLER_APPEND_PRE(handlers, ECORE_EVENT_KEY_DOWN, _e_comp_cb_key_down, NULL);
944    E_LIST_HANDLER_APPEND_PRE(handlers, ECORE_EVENT_KEY_UP, _e_comp_cb_key_up, NULL);
945 }
946