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