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