1 /**************************************************************************
5 Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: Eunchul Kim <chulspro.kim@samsung.com>,
8 JinYoung Jeon <jy0.jeon@samsung.com>,
9 Taeheon Kim <th908.kim@samsung.com>,
10 YoungJun Cho <yj44.cho@samsung.com>,
11 SooChan Lim <sc1.lim@samsung.com>,
12 Boram Park <sc1.lim@samsung.com>
14 Permission is hereby granted, free of charge, to any person obtaining a
15 copy of this software and associated documentation files (the
16 "Software"), to deal in the Software without restriction, including
17 without limitation the rights to use, copy, modify, merge, publish,
18 distribute, sub license, and/or sell copies of the Software, and to
19 permit persons to whom the Software is furnished to do so, subject to
20 the following conditions:
22 The above copyright notice and this permission notice (including the
23 next paragraph) shall be included in all copies or substantial portions
26 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
29 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
30 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
31 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
32 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 **************************************************************************/
41 #include "tdm_private.h"
44 #include <wayland-server-core.h>
46 struct _tdm_private_event {
47 struct wl_display *wl_display;
48 struct wl_event_loop *event_loop;
49 tdm_event_source *main_source;
52 typedef struct _tdm_event_source_base
54 struct wl_event_source *wl_source;
55 } tdm_event_source_base;
57 typedef struct _tdm_event_source_fd
59 tdm_event_source_base base;
60 tdm_private_display *private_display;
61 tdm_event_fd_handler func;
63 } tdm_event_source_fd;
65 typedef struct _tdm_event_source_timer
67 tdm_event_source_base base;
68 tdm_private_display *private_display;
69 tdm_event_timer_handler func;
71 } tdm_event_source_timer;
74 _tdm_event_main_fd_handler(int fd, tdm_event_mask mask, void *user_data)
76 tdm_private_display *private_display = (tdm_private_display*)user_data;
77 tdm_func_display *func_display;
79 TDM_RETURN_VAL_IF_FAIL(private_display != NULL, TDM_ERROR_OPERATION_FAILED);
81 func_display = &private_display->func_display;
82 if (!func_display->display_handle_events)
83 return TDM_ERROR_NONE;
85 return func_display->display_handle_events(private_display->bdata);
89 tdm_event_init(tdm_private_display *private_display)
91 tdm_private_event *private_event;
93 if (private_display->private_event)
94 return TDM_ERROR_NONE;
96 private_event = calloc(1, sizeof *private_event);
98 TDM_ERR("alloc failed");
99 return TDM_ERROR_OUT_OF_MEMORY;
102 private_event->wl_display = wl_display_create();
103 if (!private_event->wl_display) {
104 TDM_ERR("creating a wayland display failed");
106 return TDM_ERROR_OUT_OF_MEMORY;
109 private_event->event_loop = wl_display_get_event_loop(private_event->wl_display);
110 if (!private_event->event_loop) {
111 TDM_ERR("no event loop");
112 wl_display_destroy(private_event->wl_display);
114 return TDM_ERROR_OUT_OF_MEMORY;
117 private_display->private_event = private_event;
119 return TDM_ERROR_NONE;
123 tdm_event_deinit(tdm_private_display *private_display)
125 if (!private_display->private_event)
128 if (private_display->private_event->main_source)
129 tdm_event_source_remove(private_display->private_event->main_source);
131 if (private_display->private_event->wl_display)
132 wl_display_destroy(private_display->private_event->wl_display);
134 free(private_display->private_event);
135 private_display->private_event = NULL;
139 tdm_event_create_main_source(tdm_private_display *private_display)
141 tdm_private_event *private_event = private_display->private_event;
142 tdm_func_display *func_display;
146 TDM_RETURN_IF_FAIL(private_event != NULL);
148 func_display = &private_display->func_display;
149 if (!func_display->display_get_fd) {
150 TDM_INFO("TDM backend module won't offer a display fd");
154 ret = func_display->display_get_fd(private_display->bdata, &fd);
156 TDM_WRN("TDM backend module returns fd(%d)", fd);
160 if (!func_display->display_handle_events) {
161 TDM_ERR("no display_handle_events function");
165 private_event->main_source =
166 tdm_event_add_fd_handler(private_display, fd, TDM_EVENT_READABLE,
167 _tdm_event_main_fd_handler, private_display,
169 if (!private_event->main_source) {
170 TDM_ERR("no main event source");
174 TDM_INFO("main event source created");
178 tdm_event_get_fd(tdm_private_display *private_display)
180 tdm_private_event *private_event = private_display->private_event;
182 TDM_RETURN_VAL_IF_FAIL(private_event->event_loop != NULL, -1);
184 return wl_event_loop_get_fd(private_event->event_loop);
188 tdm_event_dispatch(tdm_private_display *private_display)
190 tdm_private_event *private_event = private_display->private_event;
192 TDM_RETURN_VAL_IF_FAIL(private_event->event_loop != NULL, TDM_ERROR_OPERATION_FAILED);
194 if (wl_event_loop_dispatch(private_event->event_loop, 0) < 0) {
195 TDM_ERR("dispatch failed");
196 return TDM_ERROR_OPERATION_FAILED;
199 return TDM_ERROR_NONE;
203 tdm_event_add_socket(tdm_private_display *private_display, const char *name)
205 tdm_private_event *private_event = private_display->private_event;
207 TDM_RETURN_VAL_IF_FAIL(private_event->wl_display != NULL, TDM_ERROR_OPERATION_FAILED);
209 if (wl_display_add_socket(private_event->wl_display, name) < 0) {
210 TDM_ERR("add socket(\"%s\") failed", name);
211 return TDM_ERROR_OPERATION_FAILED;
214 return TDM_ERROR_NONE;
218 _tdm_event_loop_fd_func(int fd, uint32_t wl_mask, void *data)
220 tdm_event_source_fd *fd_source = (tdm_event_source_fd*)data;
221 tdm_event_mask mask = 0;
223 TDM_RETURN_VAL_IF_FAIL(fd_source, 1);
224 TDM_RETURN_VAL_IF_FAIL(fd_source->func, 1);
226 if (wl_mask & WL_EVENT_READABLE)
227 mask |= TDM_EVENT_READABLE;
228 if (wl_mask & WL_EVENT_WRITABLE)
229 mask |= TDM_EVENT_WRITABLE;
230 if (wl_mask & WL_EVENT_HANGUP)
231 mask |= TDM_EVENT_HANGUP;
232 if (wl_mask & WL_EVENT_ERROR)
233 mask |= TDM_EVENT_ERROR;
235 fd_source->func(fd, mask, fd_source->user_data);
240 EXTERN tdm_event_source*
241 tdm_event_add_fd_handler(tdm_display *dpy, int fd, tdm_event_mask mask,
242 tdm_event_fd_handler func, void *user_data,
245 tdm_private_display *private_display;
246 tdm_private_event *private_event;
247 tdm_event_source_fd *fd_source;
248 uint32_t wl_mask = 0;
251 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(dpy, TDM_ERROR_INVALID_PARAMETER, NULL);
252 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(fd >= 0, TDM_ERROR_INVALID_PARAMETER, NULL);
253 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(func, TDM_ERROR_INVALID_PARAMETER, NULL);
255 private_display = (tdm_private_display*)dpy;
256 private_event = private_display->private_event;
257 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(private_event, TDM_ERROR_INVALID_PARAMETER, NULL);
258 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(private_event->event_loop, TDM_ERROR_INVALID_PARAMETER, NULL);
260 fd_source = calloc(1, sizeof(tdm_event_source_fd));
261 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(fd_source, TDM_ERROR_OUT_OF_MEMORY, NULL);
263 if (mask & TDM_EVENT_READABLE)
264 wl_mask |= WL_EVENT_READABLE;
265 if (mask & TDM_EVENT_WRITABLE)
266 wl_mask |= WL_EVENT_WRITABLE;
268 fd_source->base.wl_source =
269 wl_event_loop_add_fd(private_event->event_loop,
270 fd, wl_mask, _tdm_event_loop_fd_func, fd_source);
271 if (!fd_source->base.wl_source) {
273 *error = TDM_ERROR_OUT_OF_MEMORY;
278 fd_source->private_display = private_display;
279 fd_source->func = func;
280 fd_source->user_data = user_data;
283 *error = TDM_ERROR_NONE;
285 return (tdm_event_source*)fd_source;
289 tdm_event_source_fd_update(tdm_event_source *source, tdm_event_mask mask)
291 tdm_event_source_fd *fd_source = source;
292 uint32_t wl_mask = 0;
294 TDM_RETURN_VAL_IF_FAIL(fd_source, TDM_ERROR_INVALID_PARAMETER);
296 if (mask & TDM_EVENT_READABLE)
297 wl_mask |= WL_EVENT_READABLE;
298 if (mask & TDM_EVENT_WRITABLE)
299 wl_mask |= WL_EVENT_WRITABLE;
301 if (wl_event_source_fd_update(fd_source->base.wl_source, wl_mask) < 0) {
302 TDM_ERR("source update failed: %m");
303 return TDM_ERROR_OPERATION_FAILED;
306 return TDM_ERROR_NONE;
310 _tdm_event_loop_timer_func(void *data)
312 tdm_event_source_timer *timer_source = (tdm_event_source_timer*)data;
314 TDM_RETURN_VAL_IF_FAIL(timer_source, 1);
315 TDM_RETURN_VAL_IF_FAIL(timer_source->func, 1);
317 timer_source->func(timer_source->user_data);
322 EXTERN tdm_event_source*
323 tdm_event_add_timer_handler(tdm_display *dpy, tdm_event_timer_handler func,
324 void *user_data, tdm_error *error)
326 tdm_private_display *private_display;
327 tdm_private_event *private_event;
328 tdm_event_source_timer *timer_source;
331 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(dpy, TDM_ERROR_INVALID_PARAMETER, NULL);
332 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(func, TDM_ERROR_INVALID_PARAMETER, NULL);
334 private_display = (tdm_private_display*)dpy;
335 private_event = private_display->private_event;
336 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(private_event, TDM_ERROR_INVALID_PARAMETER, NULL);
337 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(private_event->event_loop, TDM_ERROR_INVALID_PARAMETER, NULL);
339 timer_source = calloc(1, sizeof(tdm_event_source_timer));
340 TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(timer_source, TDM_ERROR_OUT_OF_MEMORY, NULL);
342 timer_source->base.wl_source =
343 wl_event_loop_add_timer(private_event->event_loop,
344 _tdm_event_loop_timer_func, timer_source);
345 if (!timer_source->base.wl_source) {
347 *error = TDM_ERROR_OUT_OF_MEMORY;
352 timer_source->private_display = private_display;
353 timer_source->func = func;
354 timer_source->user_data = user_data;
357 *error = TDM_ERROR_NONE;
359 return (tdm_event_source*)timer_source;
363 tdm_event_source_timer_update(tdm_event_source *source, int ms_delay)
365 tdm_event_source_timer *timer_source = source;
367 TDM_RETURN_VAL_IF_FAIL(timer_source, TDM_ERROR_INVALID_PARAMETER);
369 if (wl_event_source_timer_update(timer_source->base.wl_source, ms_delay) < 0) {
370 TDM_ERR("source update failed: %m");
371 return TDM_ERROR_OPERATION_FAILED;
374 return TDM_ERROR_NONE;
378 tdm_event_source_remove(tdm_event_source *source)
380 tdm_event_source_base *base = (tdm_event_source_base*)source;
385 wl_event_source_remove(base->wl_source);