Tizen 2.1 base
[framework/uifw/ecore.git] / src / lib / ecore_evas / ecore_evas_wayland_egl.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_EGL
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
25 #include "Ecore_Evas.h"
26
27 #ifdef BUILD_ECORE_EVAS_WAYLAND_EGL
28 # include "ecore_evas_private.h"
29 # include <Evas_Engine_Wayland_Egl.h>
30 # include <Ecore_Wayland.h>
31
32 /* local function prototypes */
33 static void _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h);
34 static void _ecore_evas_wl_show(Ecore_Evas *ee);
35 static void _ecore_evas_wl_hide(Ecore_Evas *ee);
36 static void _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha);
37 static void _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent);
38
39 static Ecore_Evas_Engine_Func _ecore_wl_engine_func = 
40 {
41    _ecore_evas_wl_common_free,
42    _ecore_evas_wl_common_callback_resize_set,
43    _ecore_evas_wl_common_callback_move_set,
44    NULL, 
45    NULL,
46    _ecore_evas_wl_common_callback_delete_request_set,
47    NULL,
48    _ecore_evas_wl_common_callback_focus_in_set,
49    _ecore_evas_wl_common_callback_focus_out_set,
50    _ecore_evas_wl_common_callback_mouse_in_set,
51    _ecore_evas_wl_common_callback_mouse_out_set,
52    NULL, // sticky_set
53    NULL, // unsticky_set
54    NULL, // pre_render_set
55    NULL, // post_render_set
56    _ecore_evas_wl_common_move,
57    NULL, // managed_move
58    _ecore_evas_wl_resize,
59    NULL, // move_resize
60    NULL, // rotation_set
61    NULL, // shaped_set
62    _ecore_evas_wl_show,
63    _ecore_evas_wl_hide,
64    _ecore_evas_wl_common_raise,
65    NULL, // lower
66    NULL, // activate
67    _ecore_evas_wl_common_title_set,
68    _ecore_evas_wl_common_name_class_set,
69    _ecore_evas_wl_common_size_min_set,
70    _ecore_evas_wl_common_size_max_set,
71    _ecore_evas_wl_common_size_base_set,
72    _ecore_evas_wl_common_size_step_set,
73    NULL, // object_cursor_set
74    _ecore_evas_wl_common_layer_set,
75    NULL, // focus set
76    _ecore_evas_wl_common_iconified_set,
77    NULL, // borderless set
78    NULL, // override set
79    _ecore_evas_wl_common_maximized_set,
80    _ecore_evas_wl_common_fullscreen_set,
81    NULL, // func avoid_damage set
82    NULL, // func withdrawn set
83    NULL, // func sticky set
84    _ecore_evas_wl_common_ignore_events_set,
85    _ecore_evas_wl_alpha_set,
86    _ecore_evas_wl_transparent_set,
87    NULL, // func profiles set
88    NULL, // window group set
89    NULL, // aspect set
90    NULL, // urgent set
91    NULL, // modal set
92    NULL, // demand attention set
93    NULL, // focus skip set
94    _ecore_evas_wl_common_render,
95    _ecore_evas_wl_common_screen_geometry_get,
96    _ecore_evas_wl_common_screen_dpi_get
97 };
98
99 /* external variables */
100
101 /* external functions */
102 EAPI Ecore_Evas *
103 ecore_evas_wayland_egl_new(const char *disp_name, unsigned int parent, int x, int y, int w, int h, Eina_Bool frame)
104 {
105    Ecore_Wl_Window *p = NULL;
106    Evas_Engine_Info_Wayland_Egl *einfo;
107    Ecore_Evas *ee;
108    int method = 0, count = 0;
109
110    LOGFN(__FILE__, __LINE__, __FUNCTION__);
111
112    if (!(method = evas_render_method_lookup("wayland_egl")))
113      {
114         ERR("Render method lookup failed for Wayland_Egl");
115         return NULL;
116      }
117
118    count = ecore_wl_init(disp_name);
119    if (!count)
120      {
121         ERR("Failed to initialize Ecore_Wayland");
122         return NULL;
123      }
124    else if (count == 1)
125      ecore_wl_display_iterate();
126
127    if (!(ee = calloc(1, sizeof(Ecore_Evas))))
128      {
129         ERR("Failed to allocate Ecore_Evas");
130         goto ee_err;
131      }
132
133    ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
134
135    _ecore_evas_wl_common_init();
136
137    ee->engine.func = (Ecore_Evas_Engine_Func *)&_ecore_wl_engine_func;
138
139    ee->driver = "wayland_egl";
140    if (disp_name) ee->name = strdup(disp_name);
141
142    if (w < 1) w = 1;
143    if (h < 1) h = 1;
144
145    ee->x = x;
146    ee->y = y;
147    ee->w = w;
148    ee->h = h;
149    ee->req.x = ee->x;
150    ee->req.y = ee->y;
151    ee->req.w = ee->w;
152    ee->req.h = ee->h;
153    ee->rotation = 0;
154    ee->prop.max.w = 32767;
155    ee->prop.max.h = 32767;
156    ee->prop.layer = 4;
157    ee->prop.request_pos = 0;
158    ee->prop.sticky = 0;
159    ee->prop.draw_frame = frame;
160    ee->alpha = EINA_FALSE;
161
162    ee->evas = evas_new();
163    evas_data_attach_set(ee->evas, ee);
164    evas_output_method_set(ee->evas, method);
165    evas_output_size_set(ee->evas, ee->w, ee->h);
166    evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
167
168    /* FIXME: This needs to be set based on theme & scale */
169    if (ee->prop.draw_frame)
170      evas_output_framespace_set(ee->evas, 4, 18, 8, 22);
171
172    if (parent)
173      p = ecore_wl_window_find(parent);
174
175    /* FIXME: Get if parent is alpha, and set */
176
177    ee->engine.wl.parent = p;
178    ee->engine.wl.win = 
179      ecore_wl_window_new(p, x, y, w, h, ECORE_WL_WINDOW_BUFFER_TYPE_EGL_WINDOW);
180    ee->prop.window = ee->engine.wl.win->id;
181
182    if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas)))
183      {
184         einfo->info.display = ecore_wl_display_get();
185         einfo->info.destination_alpha = ee->alpha;
186         einfo->info.rotation = ee->rotation;
187         einfo->info.depth = 32;
188         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
189           {
190              ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
191              goto err;
192           }
193      }
194    else 
195      {
196         ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
197         goto err;
198      }
199
200    ecore_evas_callback_pre_free_set(ee, _ecore_evas_wl_common_pre_free);
201
202    if (ee->prop.draw_frame) 
203      {
204         ee->engine.wl.frame = _ecore_evas_wl_common_frame_add(ee->evas);
205         evas_object_is_frame_object_set(ee->engine.wl.frame, EINA_TRUE);
206         evas_object_move(ee->engine.wl.frame, 0, 0);
207      }
208
209    _ecore_evas_register(ee);
210    ecore_evas_input_event_register(ee);
211
212    ecore_event_window_register(ee->prop.window, ee, ee->evas, 
213                                (Ecore_Event_Mouse_Move_Cb)_ecore_evas_mouse_move_process, 
214                                (Ecore_Event_Multi_Move_Cb)_ecore_evas_mouse_multi_move_process, 
215                                (Ecore_Event_Multi_Down_Cb)_ecore_evas_mouse_multi_down_process, 
216                                (Ecore_Event_Multi_Up_Cb)_ecore_evas_mouse_multi_up_process);
217
218    return ee;
219
220  err:
221    ecore_evas_free(ee);
222    _ecore_evas_wl_common_shutdown();
223
224  ee_err:
225    ecore_wl_shutdown();
226    return NULL;
227 }
228
229 static void 
230 _ecore_evas_wl_resize(Ecore_Evas *ee, int w, int h)
231 {
232    LOGFN(__FILE__, __LINE__, __FUNCTION__);
233
234    if (!ee) return;
235    if (w < 1) w = 1;
236    if (h < 1) h = 1;
237
238    ee->req.w = w;
239    ee->req.h = h;
240
241    if (!ee->prop.fullscreen)
242      {
243         int fw = 0, fh = 0;
244
245         if (ee->prop.min.w > w) w = ee->prop.min.w;
246         else if (w > ee->prop.max.w) w = ee->prop.max.w;
247         if (ee->prop.min.h > h) h = ee->prop.min.h;
248         else if (h > ee->prop.max.h) h = ee->prop.max.h;
249
250         evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
251         w += fw;
252         h += fh;
253      }
254
255    if ((ee->w != w) || (ee->h != h))
256      {
257         ee->w = w;
258         ee->h = h;
259
260         if ((ee->rotation == 90) || (ee->rotation == 270))
261           {
262              evas_output_size_set(ee->evas, h, w);
263              evas_output_viewport_set(ee->evas, 0, 0, h, w);
264           }
265         else
266           {
267              evas_output_size_set(ee->evas, w, h);
268              evas_output_viewport_set(ee->evas, 0, 0, w, h);
269           }
270
271         if (ee->prop.avoid_damage)
272           {
273              int pdam = 0;
274
275              pdam = ecore_evas_avoid_damage_get(ee);
276              ecore_evas_avoid_damage_set(ee, 0);
277              ecore_evas_avoid_damage_set(ee, pdam);
278           }
279
280         if (ee->engine.wl.frame)
281           evas_object_resize(ee->engine.wl.frame, w, h);
282
283
284         if (ee->engine.wl.win)
285           {
286              ecore_wl_window_update_size(ee->engine.wl.win, w, h);
287              ecore_wl_window_buffer_attach(ee->engine.wl.win, NULL, 0, 0);
288           }
289
290         if (ee->func.fn_resize) ee->func.fn_resize(ee);
291      }
292 }
293
294 static void 
295 _ecore_evas_wl_show(Ecore_Evas *ee)
296 {
297    Evas_Engine_Info_Wayland_Egl *einfo;
298
299    LOGFN(__FILE__, __LINE__, __FUNCTION__);
300
301    if ((!ee) || (ee->visible)) return;
302
303    if (ee->engine.wl.win)
304      {
305         ecore_wl_window_show(ee->engine.wl.win);
306         ecore_wl_window_update_size(ee->engine.wl.win, ee->w, ee->h);
307         ecore_wl_window_buffer_attach(ee->engine.wl.win, NULL, 0, 0);
308
309         if ((ee->prop.clas) && (ee->engine.wl.win->shell_surface))
310           wl_shell_surface_set_class(ee->engine.wl.win->shell_surface, 
311                                      ee->prop.clas);
312         if ((ee->prop.title) && (ee->engine.wl.win->shell_surface))
313           wl_shell_surface_set_title(ee->engine.wl.win->shell_surface, 
314                                      ee->prop.title);
315      }
316
317    if (ee->engine.wl.frame)
318      {
319         evas_object_show(ee->engine.wl.frame);
320         evas_object_resize(ee->engine.wl.frame, ee->w, ee->h);
321      }
322
323    if (ee->engine.wl.win)
324      {
325         einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas);
326         if (!einfo)
327           {
328              ERR("Failed to get Evas Engine Info for '%s'", ee->driver);
329              return;
330           }
331
332         einfo->info.surface = ecore_wl_window_surface_get(ee->engine.wl.win);
333         /* if (einfo->info.surface) */
334         evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
335         /* else */
336         /*   printf("Failed to get a Surface from Ecore_Wl\n"); */
337      }
338
339    ee->visible = 1;
340    if (ee->func.fn_show) ee->func.fn_show(ee);
341 }
342
343 static void 
344 _ecore_evas_wl_hide(Ecore_Evas *ee)
345 {
346    Evas_Engine_Info_Wayland_Egl *einfo;
347
348    LOGFN(__FILE__, __LINE__, __FUNCTION__);
349
350    if ((!ee) || (!ee->visible)) return;
351
352    einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas);
353    if (einfo)
354      {
355         einfo->info.surface = NULL;
356         evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo);
357      }
358
359    if (ee->engine.wl.win) 
360      ecore_wl_window_hide(ee->engine.wl.win);
361
362    ee->visible = 0;
363    ee->should_be_visible = 0;
364
365    if (ee->func.fn_hide) ee->func.fn_hide(ee);
366 }
367
368 static void 
369 _ecore_evas_wl_alpha_set(Ecore_Evas *ee, int alpha)
370 {
371    Evas_Engine_Info_Wayland_Egl *einfo;
372
373    LOGFN(__FILE__, __LINE__, __FUNCTION__);
374
375    if (!ee) return;
376    if ((ee->alpha == alpha)) return;
377    ee->alpha = alpha;
378    if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas)))
379      {
380         einfo->info.destination_alpha = alpha;
381         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
382           ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
383         evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
384      }
385 }
386
387 static void 
388 _ecore_evas_wl_transparent_set(Ecore_Evas *ee, int transparent)
389 {
390    Evas_Engine_Info_Wayland_Egl *einfo;
391
392    LOGFN(__FILE__, __LINE__, __FUNCTION__);
393
394    if (!ee) return;
395    if ((ee->transparent == transparent)) return;
396    ee->transparent = transparent;
397    if (!ee->visible) return;
398    if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas)))
399      {
400         einfo->info.destination_alpha = transparent;
401         if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
402           ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
403         evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
404      }
405 }
406
407 void 
408 _ecore_evas_wayland_egl_resize(Ecore_Evas *ee, int location)
409 {
410    LOGFN(__FILE__, __LINE__, __FUNCTION__);
411
412    if (!ee) return;
413    if (ee->engine.wl.win) 
414      {
415         Evas_Engine_Info_Wayland_Egl *einfo;
416
417         if ((einfo = (Evas_Engine_Info_Wayland_Egl *)evas_engine_info_get(ee->evas)))
418           {
419              einfo->info.edges = location;
420              if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
421                ERR("evas_engine_info_set() for engine '%s' failed.", ee->driver);
422           }
423
424         ee->engine.wl.win->resizing = EINA_TRUE;
425         ecore_wl_window_resize(ee->engine.wl.win, ee->w, ee->h, location);
426      }
427 }
428 #else
429 EAPI Ecore_Evas *
430 ecore_evas_wayland_egl_new(const char *disp_name __UNUSED__, unsigned int parent __UNUSED__, int x __UNUSED__, int y __UNUSED__, int w __UNUSED__, int h __UNUSED__, Eina_Bool frame __UNUSED__)
431 {
432    return NULL;
433 }
434 #endif