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