Ecore_Evas (Wayland): Fix getting double mouse events for the wayland
[profile/ivi/ecore.git] / src / lib / ecore_evas / ecore_evas_wayland_shm.c
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4
5 //#define LOGFNS 1
6
7 #ifdef LOGFNS
8 # include <stdio.h>
9 # define LOGFN(fl, ln, fn) \
10    printf("-ECORE_EVAS-WL: %25s: %5i - %s\n", fl, ln, fn);
11 #else
12 # define LOGFN(fl, ln, fn)
13 #endif
14
15 #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
16 # include <stdlib.h>
17 # include <string.h>
18 # include <unistd.h>
19 # include <sys/types.h>
20 # include <sys/mman.h>
21 #endif
22
23 # include <Eina.h>
24 # include <Evas.h>
25 # include <Ecore.h>
26
27 # include "ecore_evas_private.h"
28 # include "Ecore_Evas.h"
29
30 #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
31 # include <Evas_Engine_Wayland_Shm.h>
32 # include <Ecore_Wayland.h>
33
34 /* local structures */
35 typedef struct _EE_Wl_Smart_Data EE_Wl_Smart_Data;
36 struct _EE_Wl_Smart_Data 
37 {
38    Evas_Object *frame;
39    Evas_Object *text;
40    Evas_Coord x, y, w, h;
41 };
42
43 /* local function prototypes */
44 static int _ecore_evas_wl_init(void);
45 static int _ecore_evas_wl_shutdown(void);
46 static void _ecore_evas_wl_pre_free(Ecore_Evas *ee);
47 static void _ecore_evas_wl_free(Ecore_Evas *ee);
48 static void _ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
49 static void _ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
50 static void _ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
51 static void _ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
52 static void _ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
53 static void _ecore_evas_wl_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee));
54 static void _ecore_evas_wl_move(Ecore_Evas *ee, int x, int y);
55 static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h);
56 static void _ecore_evas_wl_show(Ecore_Evas *ee);
57 static void _ecore_evas_wl_hide(Ecore_Evas *ee);
58 static void _ecore_evas_wl_raise(Ecore_Evas *ee);
59 static void _ecore_evas_wl_lower(Ecore_Evas *ee);
60 static void _ecore_evas_wl_activate(Ecore_Evas *ee);
61 static void _ecore_evas_wl_title_set(Ecore_Evas *ee, const char *t);
62 static void _ecore_evas_wl_name_class_set(Ecore_Evas *ee, const char *n, const char *c);
63 static void _ecore_evas_wl_size_min_set(Ecore_Evas *ee, int w, int h);
64 static void _ecore_evas_wl_size_max_set(Ecore_Evas *ee, int w, int h);
65 static void _ecore_evas_wl_size_base_set(Ecore_Evas *ee, int w, int h);
66 static void _ecore_evas_wl_size_step_set(Ecore_Evas *ee, int w, int h);
67 static void _ecore_evas_wl_object_cursor_set(Ecore_Evas *ee, Evas_Object  *obj, int layer, int hot_x, int hot_y);
68 static void _ecore_evas_wl_object_cursor_del(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__);
69 static void _ecore_evas_wl_layer_set(Ecore_Evas *ee, int layer);
70 static void _ecore_evas_wl_focus_set(Ecore_Evas *ee, int focus __UNUSED__);
71 static void _ecore_evas_wl_iconified_set(Ecore_Evas *ee, int iconify);
72 static void _ecore_evas_wl_maximized_set(Ecore_Evas *ee, int max);
73 static void _ecore_evas_wl_fullscreen_set(Ecore_Evas *ee, int full __UNUSED__);
74 static int _ecore_evas_wl_render(Ecore_Evas *ee);
75 static void _ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h);
76 static void _ecore_evas_wl_buffer_new(Ecore_Evas *ee, void **dest);
77
78 static Eina_Bool _ecore_evas_wl_event_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event);
79 static Eina_Bool _ecore_evas_wl_event_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event);
80 static Eina_Bool _ecore_evas_wl_event_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event);
81 static Eina_Bool _ecore_evas_wl_event_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event);
82
83 static void _ecore_evas_wl_handle_configure(void *data, struct wl_shell_surface *shell_surface __UNUSED__, uint32_t timestamp __UNUSED__, uint32_t edges __UNUSED__, int32_t width, int32_t height);
84 static void _ecore_evas_wl_handle_popup_done(void *data __UNUSED__, struct wl_shell_surface *shell_surface __UNUSED__);
85
86 /* SMART stuff for frame */
87 static Evas_Smart *_ecore_evas_wl_smart = NULL;
88
89 static void _ecore_evas_wl_smart_init(void);
90 static void _ecore_evas_wl_smart_add(Evas_Object *obj);
91 static void _ecore_evas_wl_smart_del(Evas_Object *obj);
92 static void _ecore_evas_wl_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
93 static void _ecore_evas_wl_smart_show(Evas_Object *obj);
94 static void _ecore_evas_wl_smart_hide(Evas_Object *obj);
95
96 static Evas_Object *_ecore_evas_wl_frame_add(Evas *evas);
97
98 /* local variables */
99 static int _ecore_evas_wl_init_count = 0;
100 static Ecore_Event_Handler *_ecore_evas_wl_event_handlers[4];
101
102 static const struct wl_shell_surface_listener _ecore_evas_wl_shell_surface_listener = 
103 {
104    _ecore_evas_wl_handle_configure,
105    _ecore_evas_wl_handle_popup_done
106 };
107
108 static Ecore_Evas_Engine_Func _ecore_wl_engine_func = 
109 {
110    _ecore_evas_wl_free, 
111    _ecore_evas_wl_callback_resize_set, 
112    _ecore_evas_wl_callback_move_set, 
113    NULL, // callback show set
114    NULL, // callback hide set
115    _ecore_evas_wl_callback_delete_request_set, 
116    NULL, // callback destroy set
117    _ecore_evas_wl_callback_focus_in_set, 
118    _ecore_evas_wl_callback_focus_out_set, 
119    _ecore_evas_wl_callback_mouse_in_set, 
120    NULL, // callback mouse out set
121    NULL, // callback sticky set
122    NULL, // callback unsticky set
123    NULL, // callback pre render set
124    NULL, // callback post render set
125    _ecore_evas_wl_move, 
126    NULL, // func managed move
127    _ecore_evas_wl_resize, 
128    NULL, // func move_resize
129    NULL, // func rotation set
130    NULL, // func shaped set
131    _ecore_evas_wl_show, 
132    _ecore_evas_wl_hide, 
133    _ecore_evas_wl_raise, 
134    _ecore_evas_wl_lower, 
135    _ecore_evas_wl_activate, 
136    _ecore_evas_wl_title_set, 
137    _ecore_evas_wl_name_class_set, 
138    _ecore_evas_wl_size_min_set, 
139    _ecore_evas_wl_size_max_set, 
140    _ecore_evas_wl_size_base_set, 
141    _ecore_evas_wl_size_step_set, 
142    _ecore_evas_wl_object_cursor_set, 
143    _ecore_evas_wl_layer_set, 
144    _ecore_evas_wl_focus_set, 
145    _ecore_evas_wl_iconified_set, 
146    NULL, // func borderless set
147    NULL, // func override set
148    _ecore_evas_wl_maximized_set, 
149    _ecore_evas_wl_fullscreen_set, 
150    NULL, // func avoid_damage set
151    NULL, // func withdrawn set
152    NULL, // func sticky set
153    NULL, // func ignore_events set
154    NULL, // func alpha set
155    NULL, // func transparent set
156    _ecore_evas_wl_render, 
157    _ecore_evas_wl_screen_geometry_get
158 };
159
160 /* external variables */
161 #endif
162
163 #ifdef BUILD_ECORE_EVAS_WAYLAND_SHM
164 EAPI Ecore_Evas *
165 ecore_evas_wayland_shm_new(const char *disp_name, int x, int y, int w, int h, int frame)
166 {
167    Evas_Engine_Info_Wayland_Shm *einfo;
168    Ecore_Evas *ee;
169    int method = 0;
170    static int _win_id = 1;
171
172    LOGFN(__FILE__, __LINE__, __FUNCTION__);
173
174    if (!(method = evas_render_method_lookup("wayland_shm"))) 
175      {
176         ERR("Render method lookup failed.");
177         return NULL;
178      }
179
180    if (!(ecore_wl_init(disp_name))) 
181      {
182         ERR("Failed to initialize Ecore Wayland.");
183         return NULL;
184      }
185
186    if (!(ee = calloc(1, sizeof(Ecore_Evas)))) 
187      {
188         ERR("Failed to allocate Ecore_Evas.");
189         ecore_wl_shutdown();
190         return NULL;
191      }
192
193    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
194
195    _ecore_evas_wl_init();
196
197    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wl_engine_func;
198
199    ee->driver = "wayland_shm";
200    if (disp_name) ee->name = strdup(disp_name);
201
202    if (w < 1) w = 1;
203    if (h < 1) h = 1;
204
205    ee->req.x = ee->x = x;
206    ee->req.y = ee->y = y;
207    ee->req.w = ee->w = w;
208    ee->req.h = ee->h = h;
209    ee->rotation = 0;
210    ee->prop.max.w = ee->prop.max.h = 32767;
211    ee->prop.layer = 4;
212    ee->prop.request_pos = 0;
213    ee->prop.sticky = 0;
214    ee->prop.draw_frame = frame;
215    ee->prop.window = _win_id++;
216
217    ee->evas = evas_new();
218    evas_data_attach_set(ee->evas, ee);
219    evas_output_method_set(ee->evas, method);
220    evas_output_size_set(ee->evas, ee->w, ee->h);
221    evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
222
223    if (ee->prop.draw_frame) 
224      evas_output_framespace_set(ee->evas, 4, 18, 8, 22);
225
226    if ((einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas))) 
227      {
228         einfo->info.rotation = ee->rotation;
229         einfo->info.debug = EINA_FALSE;
230         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo)) 
231           {
232              ERR("Failed to set Evas Engine Info for '%s'.", ee->driver);
233              ecore_evas_free(ee);
234              return NULL;
235           }
236      }
237    else 
238      {
239         ERR("Failed to get Evas Engine Info for '%s'.", ee->driver);
240         ecore_evas_free(ee);
241         return NULL;
242      }
243
244    /* NB: we need to be notified before 'free' so we can munmap the evas 
245     * engine destination */
246    ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_pre_free);
247
248    if (ee->prop.draw_frame) 
249      {
250         ee->engine.wl.frame = _ecore_evas_wl_frame_add(ee->evas);
251         evas_object_is_frame_object_set(ee->engine.wl.frame, EINA_TRUE);
252         evas_object_move(ee->engine.wl.frame, 0, 0);
253      }
254
255    ecore_evas_input_event_register(ee);
256    _ecore_evas_register(ee);
257
258    ecore_event_window_register(ee->prop.window, ee, ee->evas, 
259                                (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, 
260                                (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, 
261                                (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, 
262                                (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
263
264    evas_event_feed_mouse_in(ee->evas, (unsigned int)((unsigned long long)(ecore_time_get() * 1000.0) & 0xffffffff), NULL);
265
266    return ee;
267 }
268
269 /* local functions */
270 static int 
271 _ecore_evas_wl_init(void)
272 {
273    LOGFN(__FILE__, __LINE__, __FUNCTION__);
274
275    if (++_ecore_evas_wl_init_count != 1)
276      return _ecore_evas_wl_init_count;
277
278    _ecore_evas_wl_event_handlers[0] = 
279      ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_IN, 
280                              _ecore_evas_wl_event_mouse_in, NULL);
281    _ecore_evas_wl_event_handlers[1] = 
282      ecore_event_handler_add(ECORE_WL_EVENT_MOUSE_OUT, 
283                              _ecore_evas_wl_event_mouse_out, NULL);
284    _ecore_evas_wl_event_handlers[2] = 
285      ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_IN, 
286                              _ecore_evas_wl_event_focus_in, NULL);
287    _ecore_evas_wl_event_handlers[3] = 
288      ecore_event_handler_add(ECORE_WL_EVENT_FOCUS_OUT, 
289                              _ecore_evas_wl_event_focus_out, NULL);
290
291    ecore_event_evas_init();
292
293    return _ecore_evas_wl_init_count;
294 }
295
296 static int 
297 _ecore_evas_wl_shutdown(void)
298 {
299    unsigned int i = 0;
300
301    LOGFN(__FILE__, __LINE__, __FUNCTION__);
302
303    if (--_ecore_evas_wl_init_count != 0)
304      return _ecore_evas_wl_init_count;
305
306    for (i = 0; i < sizeof(_ecore_evas_wl_event_handlers) / sizeof(Ecore_Event_Handler *); i++) 
307      {
308         if (_ecore_evas_wl_event_handlers[i])
309           ecore_event_handler_del(_ecore_evas_wl_event_handlers[i]);
310      }
311
312    ecore_event_evas_shutdown();
313
314    return _ecore_evas_wl_init_count;
315 }
316
317 static void 
318 _ecore_evas_wl_pre_free(Ecore_Evas *ee)
319 {
320    Evas_Engine_Info_Wayland_Shm *einfo;
321
322    LOGFN(__FILE__, __LINE__, __FUNCTION__);
323
324    /* destroy frame */
325    if (ee->engine.wl.frame) evas_object_del(ee->engine.wl.frame);
326
327    /* get engine info */
328    einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
329    if ((einfo) && (einfo->info.dest))
330      {
331         int ret = 0;
332
333         /* munmap previous engine destination */
334         ret = munmap(einfo->info.dest, ((ee->w * sizeof(int)) * ee->h));
335      }
336 }
337
338 static void 
339 _ecore_evas_wl_free(Ecore_Evas *ee)
340 {
341    LOGFN(__FILE__, __LINE__, __FUNCTION__);
342
343    /* destroy buffer */
344    if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
345    ee->engine.wl.buffer = NULL;
346
347    /* destroy shell surface */
348    if (ee->engine.wl.shell_surface)
349      wl_shell_surface_destroy(ee->engine.wl.shell_surface);
350    ee->engine.wl.shell_surface = NULL;
351
352    /* destroy surface */
353    if (ee->engine.wl.surface) wl_surface_destroy(ee->engine.wl.surface);
354    ee->engine.wl.surface = NULL;
355
356    ecore_event_window_unregister(ee->prop.window);
357    ecore_evas_input_event_unregister(ee);
358
359    _ecore_evas_wl_shutdown();
360    ecore_wl_shutdown();
361 }
362
363 static void 
364 _ecore_evas_wl_callback_resize_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
365 {
366    LOGFN(__FILE__, __LINE__, __FUNCTION__);
367
368    if (!ee) return;
369    ee->func.fn_resize = func;
370 }
371
372 static void 
373 _ecore_evas_wl_callback_move_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
374 {
375    LOGFN(__FILE__, __LINE__, __FUNCTION__);
376
377    if (!ee) return;
378    ee->func.fn_move = func;
379 }
380
381 static void 
382 _ecore_evas_wl_callback_delete_request_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
383 {
384    LOGFN(__FILE__, __LINE__, __FUNCTION__);
385
386    if (!ee) return;
387    ee->func.fn_delete_request = func;
388 }
389
390 static void 
391 _ecore_evas_wl_callback_focus_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
392 {
393    LOGFN(__FILE__, __LINE__, __FUNCTION__);
394
395    if (!ee) return;
396    ee->func.fn_focus_in = func;
397 }
398
399 static void 
400 _ecore_evas_wl_callback_focus_out_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
401 {
402    LOGFN(__FILE__, __LINE__, __FUNCTION__);
403
404    if (!ee) return;
405    ee->func.fn_focus_out = func;
406 }
407
408 static void 
409 _ecore_evas_wl_callback_mouse_in_set(Ecore_Evas *ee, void (*func)(Ecore_Evas *ee))
410 {
411    LOGFN(__FILE__, __LINE__, __FUNCTION__);
412
413    if (!ee) return;
414    ee->func.fn_mouse_in = func;
415 }
416
417 static void 
418 _ecore_evas_wl_move(Ecore_Evas *ee, int x, int y) 
419 {
420    LOGFN(__FILE__, __LINE__, __FUNCTION__);
421
422    if (!ee) return;
423 //   if ((ee->x == x) && (ee->y == y)) return;
424    ee->req.x = x;
425    ee->req.y = y;
426
427    ee->x = x;
428    ee->y = y;
429
430    if (ee->engine.wl.shell_surface)
431      {
432         wl_shell_surface_move(ee->engine.wl.shell_surface, 
433                               ecore_wl_input_device_get(), 
434                               ecore_wl_input_timestamp_get());
435      }
436
437    if (ee->func.fn_move) ee->func.fn_move(ee);
438 }
439
440 static void 
441 _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h)
442 {
443    Evas_Engine_Info_Wayland_Shm *einfo;
444
445    LOGFN(__FILE__, __LINE__, __FUNCTION__);
446
447    if (!ee) return;
448    if (w < 1) w = 1;
449    if (h < 1) h = 1;
450    if ((ee->w == w) && (ee->h == h)) return;
451
452    if (ee->prop.min.w > w) w = ee->prop.min.w;
453    else if (w > ee->prop.max.w) w = ee->prop.max.w;
454
455    if (ee->prop.min.h > h) h = ee->prop.min.h;
456    else if (h > ee->prop.max.h) h = ee->prop.max.h;
457
458    ee->req.w = w;
459    ee->req.h = h;
460
461    if (ee->visible) 
462      {
463         /* damage old surface, if it exists */
464
465         /* NB: This removes any lingering screen artifacts in the compositor.
466          * This may be a 'HACK' if the issue is actually in the wayland 
467          * compositor, but for now lets implement this so we don't have screen 
468          * artifacts laying around during a resize */
469         if (ee->engine.wl.surface)
470           wl_surface_damage(ee->engine.wl.surface, 0, 0, ee->w, ee->h);
471      }
472
473    /* get engine info */
474    einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
475    if (einfo->info.dest)
476      {
477         int ret = 0;
478
479         /* munmap previous engine destination */
480         ret = munmap(einfo->info.dest, ((ee->w * sizeof(int)) * ee->h));
481      }
482
483    /* free old buffer */
484    if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
485    ee->engine.wl.buffer = NULL;
486
487    ee->w = w;
488    ee->h = h;
489
490    /* create buffer @ new size (also mmaps the new destination) */
491    _ecore_evas_wl_buffer_new(ee, &einfo->info.dest);
492
493    /* flush new buffer fd */
494    ecore_wl_flush();
495
496    /* change evas output & viewport sizes */
497    evas_output_size_set(ee->evas, ee->w, ee->h);
498    evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
499    evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
500    if (ee->engine.wl.frame)
501      evas_object_resize(ee->engine.wl.frame, ee->w, ee->h);
502
503    /* set new engine destination */
504    evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
505
506    /* damage buffer */
507    wl_buffer_damage(ee->engine.wl.buffer, 0, 0, ee->w, ee->h);
508
509    if (ee->visible) 
510      {
511         /* damage surface */
512         wl_surface_damage(ee->engine.wl.surface, 0, 0, ee->w, ee->h);
513
514         /* if visible, attach to surface */
515         wl_surface_attach(ee->engine.wl.surface, ee->engine.wl.buffer, 0, 0);
516      }
517
518    if (ee->func.fn_resize) ee->func.fn_resize(ee);
519 }
520
521 static void 
522 _ecore_evas_wl_show(Ecore_Evas *ee)
523 {
524    Evas_Engine_Info_Wayland_Shm *einfo;
525
526    LOGFN(__FILE__, __LINE__, __FUNCTION__);
527
528    if (!ee) return;
529    if (ee->visible) return;
530
531    /* get engine info */
532    einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
533
534    /* create new surface */
535    ee->engine.wl.surface = 
536      wl_compositor_create_surface(ecore_wl_compositor_get());
537    wl_surface_set_user_data(ee->engine.wl.surface, (void *)ee->prop.window);
538
539    /* get new shell surface */
540    ee->engine.wl.shell_surface = 
541      wl_shell_get_shell_surface(ecore_wl_shell_get(), ee->engine.wl.surface);
542
543    /* set toplevel */
544    wl_shell_surface_set_toplevel(ee->engine.wl.shell_surface);
545
546    /* create buffer @ new size (also mmaps the new destination) */
547    _ecore_evas_wl_buffer_new(ee, &einfo->info.dest);
548
549    if (ee->engine.wl.frame) 
550      {
551         evas_object_show(ee->engine.wl.frame);
552         evas_object_resize(ee->engine.wl.frame, ee->w, ee->h);
553      }
554
555    /* set new engine destination */
556    evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
557
558    /* add configure listener for wayland resize events */
559    wl_shell_surface_add_listener(ee->engine.wl.shell_surface, 
560                                  &_ecore_evas_wl_shell_surface_listener, ee);
561
562    /* flush new buffer fd */
563    ecore_wl_flush();
564
565    /* attach buffer to surface */
566    wl_surface_attach(ee->engine.wl.surface, ee->engine.wl.buffer, 0, 0);
567
568    /* NB: No need to do a damage here. If we do, we end up w/ screen 
569     * artifacts in the compositor */
570    /* wl_surface_damage(ee->engine.wl.surface, 0, 0, ee->w, ee->h); */
571
572    ee->visible = 1;
573    if (ee->func.fn_show) ee->func.fn_show(ee);
574 }
575
576 static void 
577 _ecore_evas_wl_hide(Ecore_Evas *ee) 
578 {
579    Evas_Engine_Info_Wayland_Shm *einfo;
580
581    LOGFN(__FILE__, __LINE__, __FUNCTION__);
582
583    if (!ee) return;
584    if (!ee->visible) return;
585
586    /* get engine info */
587    einfo = (Evas_Engine_Info_Wayland_Shm *)evas_engine_info_get(ee->evas);
588    if (einfo->info.dest)
589      {
590         int ret = 0;
591
592         /* munmap previous engine destination */
593         ret = munmap(einfo->info.dest, ((ee->w * sizeof(int)) * ee->h));
594         einfo->info.dest = NULL;
595      }
596
597    /* free old buffer */
598    if (ee->engine.wl.buffer) wl_buffer_destroy(ee->engine.wl.buffer);
599    ee->engine.wl.buffer = NULL;
600
601    /* set new engine destination */
602    evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
603
604    /* destroy shell surface */
605    if (ee->engine.wl.shell_surface) 
606      wl_shell_surface_destroy(ee->engine.wl.shell_surface);
607    ee->engine.wl.shell_surface = NULL;
608
609    /* destroy surface */
610    if (ee->engine.wl.surface) wl_surface_destroy(ee->engine.wl.surface);
611    ee->engine.wl.surface = NULL;
612
613    ee->visible = 0;
614    ee->should_be_visible = 0;
615    if (ee->func.fn_hide) ee->func.fn_hide(ee);
616 }
617
618 static void 
619 _ecore_evas_wl_raise(Ecore_Evas *ee)
620 {
621    LOGFN(__FILE__, __LINE__, __FUNCTION__);
622
623    if ((!ee) || (!ee->visible)) return;
624    if (!ee->engine.wl.shell_surface) return;
625    wl_shell_surface_set_toplevel(ee->engine.wl.shell_surface);
626 }
627
628 static void 
629 _ecore_evas_wl_lower(Ecore_Evas *ee)
630 {
631    LOGFN(__FILE__, __LINE__, __FUNCTION__);
632
633    if ((!ee) || (!ee->visible)) return;
634    /* FIXME: Need a way to tell Wayland to lower */
635 }
636
637 static void 
638 _ecore_evas_wl_activate(Ecore_Evas *ee)
639 {
640    LOGFN(__FILE__, __LINE__, __FUNCTION__);
641
642    if ((!ee) || (!ee->visible)) return;
643    if (!ee->engine.wl.shell_surface) return;
644    wl_shell_surface_set_toplevel(ee->engine.wl.shell_surface);
645 }
646
647 static void 
648 _ecore_evas_wl_title_set(Ecore_Evas *ee, const char *t) 
649 {
650    LOGFN(__FILE__, __LINE__, __FUNCTION__);
651
652    if (!ee) return;
653    if (ee->prop.title) free(ee->prop.title);
654    ee->prop.title = NULL;
655    if (t) ee->prop.title = strdup(t);
656
657    if ((ee->prop.draw_frame) && (ee->engine.wl.frame)) 
658      {
659         EE_Wl_Smart_Data *sd;
660
661         if (!(sd = evas_object_smart_data_get(ee->engine.wl.frame))) return;
662         evas_object_text_text_set(sd->text, ee->prop.title);
663      }
664 }
665
666 static void 
667 _ecore_evas_wl_name_class_set(Ecore_Evas *ee, const char *n, const char *c) 
668 {
669    LOGFN(__FILE__, __LINE__, __FUNCTION__);
670
671    if (!ee) return;
672    if (ee->prop.name) free(ee->prop.name);
673    if (ee->prop.clas) free(ee->prop.clas);
674    ee->prop.name = NULL;
675    ee->prop.clas = NULL;
676    if (n) ee->prop.name = strdup(n);
677    if (c) ee->prop.clas = strdup(c);
678    /* FIXME: Forward these changes to Wayland somehow */
679 }
680
681 static void 
682 _ecore_evas_wl_size_min_set(Ecore_Evas *ee, int w, int h) 
683 {
684    LOGFN(__FILE__, __LINE__, __FUNCTION__);
685
686    if (!ee) return;
687    if (w < 0) w = 0;
688    if (h < 0) h = 0;
689    if ((ee->prop.min.w == w) && (ee->prop.min.h == h)) return;
690    ee->prop.min.w = w;
691    ee->prop.min.h = h;
692 }
693
694 static void 
695 _ecore_evas_wl_size_max_set(Ecore_Evas *ee, int w, int h) 
696 {
697    LOGFN(__FILE__, __LINE__, __FUNCTION__);
698
699    if (!ee) return;
700    if (w < 0) w = 0;
701    if (h < 0) h = 0;
702    if ((ee->prop.max.w == w) && (ee->prop.max.h == h)) return;
703    ee->prop.max.w = w;
704    ee->prop.max.h = h;
705 }
706
707 static void 
708 _ecore_evas_wl_size_base_set(Ecore_Evas *ee, int w, int h) 
709 {
710    LOGFN(__FILE__, __LINE__, __FUNCTION__);
711
712    if (!ee) return;
713    if (w < 0) w = 0;
714    if (h < 0) h = 0;
715    if ((ee->prop.base.w == w) && (ee->prop.base.h == h)) return;
716    ee->prop.base.w = w;
717    ee->prop.base.h = h;
718 }
719
720 static void 
721 _ecore_evas_wl_size_step_set(Ecore_Evas *ee, int w, int h) 
722 {
723    LOGFN(__FILE__, __LINE__, __FUNCTION__);
724
725    if (!ee) return;
726    if (w < 0) w = 0;
727    if (h < 0) h = 0;
728    if ((ee->prop.step.w == w) && (ee->prop.step.h == h)) return;
729    ee->prop.step.w = w;
730    ee->prop.step.h = h;
731 }
732
733 static void 
734 _ecore_evas_wl_object_cursor_set(Ecore_Evas *ee, Evas_Object  *obj, int layer, int hot_x, int hot_y) 
735 {
736    int x = 0, y = 0;
737
738    LOGFN(__FILE__, __LINE__, __FUNCTION__);
739
740    if (!ee) return;
741    if (ee->prop.cursor.object) evas_object_del(ee->prop.cursor.object);
742    ee->prop.cursor.object = NULL;
743
744    if (!obj) 
745      {
746         ee->prop.cursor.layer = 0;
747         ee->prop.cursor.hot.x = 0;
748         ee->prop.cursor.hot.y = 0;
749         return;
750      }
751
752    ee->prop.cursor.object = obj;
753    ee->prop.cursor.layer = layer;
754    ee->prop.cursor.hot.x = hot_x;
755    ee->prop.cursor.hot.y = hot_y;
756
757    evas_pointer_output_xy_get(ee->evas, &x, &y);
758    evas_object_layer_set(ee->prop.cursor.object, ee->prop.cursor.layer);
759    evas_object_move(ee->prop.cursor.object, 
760                     x - ee->prop.cursor.hot.x, y - ee->prop.cursor.hot.y);
761    evas_object_pass_events_set(ee->prop.cursor.object, 1);
762    if (evas_pointer_inside_get(ee->evas))
763      evas_object_show(ee->prop.cursor.object);
764
765    evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, 
766                                   _ecore_evas_wl_object_cursor_del, ee);
767 }
768
769 static void 
770 _ecore_evas_wl_object_cursor_del(void *data, Evas *evas __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__) 
771 {
772    Ecore_Evas *ee;
773
774    if (!(ee = data)) return;
775    ee->prop.cursor.object = NULL;
776 }
777
778 static void 
779 _ecore_evas_wl_layer_set(Ecore_Evas *ee, int layer)
780 {
781    LOGFN(__FILE__, __LINE__, __FUNCTION__);
782
783    if (!ee) return;
784    if (ee->prop.layer == layer) return;
785    if (layer < 1) layer = 1;
786    else if (layer > 255) layer = 255;
787    ee->prop.layer = layer;
788 }
789
790 static void 
791 _ecore_evas_wl_focus_set(Ecore_Evas *ee, int focus __UNUSED__)
792 {
793    LOGFN(__FILE__, __LINE__, __FUNCTION__);
794
795    if ((!ee) || (!ee->visible)) return;
796    if (!ee->engine.wl.shell_surface) return;
797    wl_shell_surface_set_toplevel(ee->engine.wl.shell_surface);
798 }
799
800 static void 
801 _ecore_evas_wl_iconified_set(Ecore_Evas *ee, int iconify)
802 {
803    LOGFN(__FILE__, __LINE__, __FUNCTION__);
804
805    if (!ee) return;
806    if (ee->prop.iconified == iconify) return;
807    ee->prop.iconified = iconify;
808    /* FIXME: Implement this in Wayland someshow */
809 }
810
811 static void 
812 _ecore_evas_wl_maximized_set(Ecore_Evas *ee, int max)
813 {
814    LOGFN(__FILE__, __LINE__, __FUNCTION__);
815
816    if (!ee) return;
817    if (ee->prop.maximized == max) return;
818    ee->prop.maximized = max;
819    /* FIXME: Implement this. Support is in Wayland now */
820 }
821
822 static void 
823 _ecore_evas_wl_fullscreen_set(Ecore_Evas *ee, int full __UNUSED__)
824 {
825    LOGFN(__FILE__, __LINE__, __FUNCTION__);
826
827    if ((!ee) || (!ee->visible)) return;
828    if (!ee->engine.wl.shell_surface) return;
829    wl_shell_surface_set_fullscreen(ee->engine.wl.shell_surface);
830 }
831
832 static int 
833 _ecore_evas_wl_render(Ecore_Evas *ee)
834 {
835    int rend = 0;
836
837    if (!ee) return 0;
838    if (!ee->visible) 
839      evas_norender(ee->evas);
840    else 
841      {
842         Eina_List *ll = NULL, *updates = NULL;
843         Ecore_Evas *ee2 = NULL;
844
845         if (ee->func.fn_pre_render) ee->func.fn_pre_render(ee);
846
847         EINA_LIST_FOREACH(ee->sub_ecore_evas, ll, ee2) 
848           {
849              if (ee2->func.fn_pre_render) ee2->func.fn_pre_render(ee2);
850              if (ee2->engine.func->fn_render)
851                rend |= ee2->engine.func->fn_render(ee2);
852              if (ee2->func.fn_post_render) ee2->func.fn_post_render(ee2);
853           }
854
855         if ((updates = evas_render_updates(ee->evas))) 
856           {
857              Eina_List *l = NULL;
858              Eina_Rectangle *r;
859
860              EINA_LIST_FOREACH(updates, l, r) 
861                {
862                   if (ee->engine.wl.buffer)
863                     wl_buffer_damage(ee->engine.wl.buffer, 
864                                      r->x, r->y, r->w, r->h);
865
866                   if (ee->engine.wl.surface)
867                     wl_surface_damage(ee->engine.wl.surface, 
868                                       r->x, r->y, r->w, r->h);
869                }
870
871              evas_render_updates_free(updates);
872              _ecore_evas_idle_timeout_update(ee);
873              rend = 1;
874
875              ecore_wl_flush();
876           }
877
878         if (ee->func.fn_post_render) ee->func.fn_post_render(ee);
879      }
880
881    return rend;
882 }
883
884 static void 
885 _ecore_evas_wl_screen_geometry_get(const Ecore_Evas *ee __UNUSED__, int *x, int *y, int *w, int *h)
886 {
887    LOGFN(__FILE__, __LINE__, __FUNCTION__);
888
889    if (x) *x = 0;
890    if (y) *y = 0;
891    ecore_wl_screen_size_get(w, h);
892 }
893
894 static Eina_Bool 
895 _ecore_evas_wl_event_mouse_in(void *data __UNUSED__, int type __UNUSED__, void *event)
896 {
897    Ecore_Evas *ee;
898    Ecore_Wl_Event_Mouse_In *ev;
899
900    LOGFN(__FILE__, __LINE__, __FUNCTION__);
901
902    ev = event;
903    ee = ecore_event_window_match(ev->window);
904    if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
905    if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
906    if (ee->func.fn_mouse_in) ee->func.fn_mouse_in(ee);
907    ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers);
908    evas_event_feed_mouse_in(ee->evas, ev->time, NULL);
909    _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->time);
910    return ECORE_CALLBACK_PASS_ON;
911 }
912
913 static Eina_Bool 
914 _ecore_evas_wl_event_mouse_out(void *data __UNUSED__, int type __UNUSED__, void *event)
915 {
916    Ecore_Evas *ee;
917    Ecore_Wl_Event_Mouse_Out *ev;
918
919    LOGFN(__FILE__, __LINE__, __FUNCTION__);
920
921    ev = event;
922    ee = ecore_event_window_match(ev->window);
923    if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
924    if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
925    ecore_event_evas_modifier_lock_update(ee->evas, ev->modifiers);
926    _ecore_evas_mouse_move_process(ee, ev->x, ev->y, ev->time);
927    evas_event_feed_mouse_out(ee->evas, ev->time, NULL);
928    if (ee->func.fn_mouse_out) ee->func.fn_mouse_out(ee);
929    if (ee->prop.cursor.object) evas_object_hide(ee->prop.cursor.object);
930    return ECORE_CALLBACK_PASS_ON;
931 }
932
933 static Eina_Bool 
934 _ecore_evas_wl_event_focus_in(void *data __UNUSED__, int type __UNUSED__, void *event)
935 {
936    Ecore_Evas *ee;
937    Ecore_Wl_Event_Focus_In *ev;
938
939    LOGFN(__FILE__, __LINE__, __FUNCTION__);
940
941    ev = event;
942    ee = ecore_event_window_match(ev->window);
943    if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
944    if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
945    ee->prop.focused = 1;
946    evas_focus_in(ee->evas);
947    if (ee->func.fn_focus_in) ee->func.fn_focus_in(ee);
948    return ECORE_CALLBACK_PASS_ON;
949 }
950
951 static Eina_Bool 
952 _ecore_evas_wl_event_focus_out(void *data __UNUSED__, int type __UNUSED__, void *event)
953 {
954    Ecore_Evas *ee;
955    Ecore_Wl_Event_Focus_Out *ev;
956
957    LOGFN(__FILE__, __LINE__, __FUNCTION__);
958
959    ev = event;
960    ee = ecore_event_window_match(ev->window);
961    if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
962    if (ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
963    evas_focus_out(ee->evas);
964    ee->prop.focused = 0;
965    if (ee->func.fn_focus_out) ee->func.fn_focus_out(ee);
966    return ECORE_CALLBACK_PASS_ON;
967 }
968
969 static void 
970 _ecore_evas_wl_handle_configure(void *data, struct wl_shell_surface *shell_surface, uint32_t timestamp __UNUSED__, uint32_t edges __UNUSED__, int32_t width, int32_t height) 
971 {
972    Ecore_Evas *ee;
973
974    /* NB: Trap to prevent compositor from crashing */
975    if ((width <= 0) || (height <= 0)) return;
976
977    if (!(ee = data)) return;
978
979    if ((shell_surface) && (ee->engine.wl.shell_surface)) 
980      {
981         if (ee->engine.wl.shell_surface != shell_surface) return;
982         ecore_evas_resize(ee, width, height);
983      }
984 }
985
986 static void 
987 _ecore_evas_wl_handle_popup_done(void *data __UNUSED__, struct wl_shell_surface *shell_surface __UNUSED__) 
988 {
989
990 }
991
992 static void 
993 _ecore_evas_wl_buffer_new(Ecore_Evas *ee, void **dest)
994 {
995    struct wl_shm *shm;
996    static unsigned int format;
997    char tmp[PATH_MAX];
998    int fd = -1, stride = 0, size = 0;
999    void *ret;
1000
1001    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1002
1003    if (dest) *dest = NULL;
1004    if (!(shm = ecore_wl_shm_get())) return;
1005    if (!format) format = ecore_wl_format_get();
1006
1007    strcpy(tmp, "/tmp/ecore-wayland_shm-XXXXXX");
1008    if ((fd = mkstemp(tmp)) < 0) 
1009      {
1010         ERR("Could not create temporary file.");
1011         return;
1012      }
1013
1014    stride = (ee->w * sizeof(int));
1015    size = (stride * ee->h);
1016    if (ftruncate(fd, size) < 0) 
1017      {
1018         ERR("Could not truncate temporary file.");
1019         close(fd);
1020         return;
1021      }
1022
1023    ret = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, 0);
1024    unlink(tmp);
1025
1026    if (ret == MAP_FAILED) 
1027      {
1028         ERR("mmap of temporary file failed.");
1029         close(fd);
1030         return;
1031      }
1032
1033    if (dest) *dest = ret;
1034
1035    ee->engine.wl.buffer = 
1036      wl_shm_create_buffer(ecore_wl_shm_get(), fd, ee->w, ee->h, stride, format);
1037
1038    close(fd);
1039 }
1040
1041 static void 
1042 _ecore_evas_wl_smart_init(void) 
1043 {
1044    if (_ecore_evas_wl_smart) return;
1045      {
1046         static const Evas_Smart_Class sc = 
1047           {
1048              "ecore_evas_wl_frame", EVAS_SMART_CLASS_VERSION, 
1049              _ecore_evas_wl_smart_add, 
1050              _ecore_evas_wl_smart_del, 
1051              NULL, 
1052              _ecore_evas_wl_smart_resize, 
1053              _ecore_evas_wl_smart_show, 
1054              _ecore_evas_wl_smart_hide, 
1055              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
1056           };
1057         _ecore_evas_wl_smart = evas_smart_class_new(&sc);
1058      }
1059 }
1060
1061 static void 
1062 _ecore_evas_wl_smart_add(Evas_Object *obj) 
1063 {
1064    EE_Wl_Smart_Data *sd;
1065    Evas *evas;
1066
1067    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1068
1069    if (!(sd = calloc(1, sizeof(EE_Wl_Smart_Data)))) return;
1070
1071    evas = evas_object_evas_get(obj);
1072
1073    sd->x = 0;
1074    sd->y = 0;
1075    sd->w = 1;
1076    sd->h = 1;
1077
1078    sd->frame = evas_object_rectangle_add(evas);
1079    evas_object_is_frame_object_set(sd->frame, EINA_TRUE);
1080    evas_object_color_set(sd->frame, 249, 249, 249, 255);
1081    evas_object_smart_member_add(sd->frame, obj);
1082
1083    sd->text = evas_object_text_add(evas);
1084    evas_object_color_set(sd->text, 0, 0, 0, 255);
1085    evas_object_text_style_set(sd->text, EVAS_TEXT_STYLE_PLAIN);
1086    evas_object_text_font_set(sd->text, "Sans", 10);
1087    evas_object_text_text_set(sd->text, "Smart Test");
1088
1089    evas_object_smart_data_set(obj, sd);
1090 }
1091
1092 static void 
1093 _ecore_evas_wl_smart_del(Evas_Object *obj) 
1094 {
1095    EE_Wl_Smart_Data *sd;
1096
1097    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1098
1099    if (!(sd = evas_object_smart_data_get(obj))) return;
1100    evas_object_del(sd->text);
1101    evas_object_del(sd->frame);
1102    free(sd);
1103 }
1104
1105 static void 
1106 _ecore_evas_wl_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) 
1107 {
1108    EE_Wl_Smart_Data *sd;
1109
1110    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1111
1112    if (!(sd = evas_object_smart_data_get(obj))) return;
1113    if ((sd->w == w) && (sd->h == h)) return;
1114    sd->w = w;
1115    sd->h = h;
1116    evas_object_resize(sd->frame, w, h);
1117 }
1118
1119 static void 
1120 _ecore_evas_wl_smart_show(Evas_Object *obj) 
1121 {
1122    EE_Wl_Smart_Data *sd;
1123
1124    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1125
1126    if (!(sd = evas_object_smart_data_get(obj))) return;
1127    evas_object_show(sd->frame);
1128    evas_object_show(sd->text);
1129 }
1130
1131 static void 
1132 _ecore_evas_wl_smart_hide(Evas_Object *obj) 
1133 {
1134    EE_Wl_Smart_Data *sd;
1135
1136    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1137
1138    if (!(sd = evas_object_smart_data_get(obj))) return;
1139    evas_object_hide(sd->text);
1140    evas_object_hide(sd->frame);
1141 }
1142
1143 static Evas_Object *
1144 _ecore_evas_wl_frame_add(Evas *evas) 
1145 {
1146    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1147
1148    _ecore_evas_wl_smart_init();
1149    return evas_object_smart_add(evas, _ecore_evas_wl_smart);
1150 }
1151
1152 void 
1153 _ecore_evas_wayland_shm_resize(Ecore_Evas *ee, int location)
1154 {
1155    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1156
1157    if ((!ee) || (!ee->engine.wl.shell_surface)) return;
1158    wl_shell_surface_resize(ee->engine.wl.shell_surface, 
1159                            ecore_wl_input_device_get(), 
1160                            ecore_wl_input_timestamp_get(), location);
1161 }
1162
1163 void 
1164 _ecore_evas_wayland_shm_drag_start(Ecore_Evas *ee, Ecore_Evas *drag_ee, void *source)
1165 {
1166    LOGFN(__FILE__, __LINE__, __FUNCTION__);
1167
1168    if ((!ee) || (!ee->engine.wl.surface)) return;
1169    if ((!source) || (!drag_ee)) return;
1170    ecore_wl_drag_start(source, ee->engine.wl.surface, drag_ee->engine.wl.buffer);
1171 }
1172
1173 #else
1174 EAPI Ecore_Evas *
1175 ecore_evas_wayland_shm_new(const char *disp_name __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__, int frame __UNUSED__)
1176 {
1177    return NULL;
1178 }
1179 #endif