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