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