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 **************************************************************************/
44 #include "tdm_client.h"
46 #include "tdm_macro.h"
48 #include "tdm-client-protocol.h"
52 typedef struct _tdm_private_client {
53 struct wl_display *display;
54 struct wl_registry *registry;
57 struct list_head vblank_list;
60 typedef struct _tdm_client_vblank_info {
61 struct list_head link;
62 struct wl_tdm_vblank *vblank;
63 tdm_client_vblank_handler func;
65 } tdm_client_vblank_info;
68 _tdm_client_cb_global(void *data, struct wl_registry *registry,
69 uint32_t name, const char *interface,
72 tdm_private_client *private_client = data;
74 if (strcmp(interface, "wl_tdm") == 0) {
76 wl_registry_bind(registry, name, &wl_tdm_interface, version);
77 TDM_RETURN_IF_FAIL(private_client->tdm != NULL);
79 wl_display_flush(private_client->display);
84 _tdm_client_cb_global_remove(void *data, struct wl_registry *registry, uint32_t name)
88 static const struct wl_registry_listener tdm_client_registry_listener =
90 _tdm_client_cb_global,
91 _tdm_client_cb_global_remove
95 tdm_client_create(tdm_client_error *error)
97 tdm_private_client *private_client;
99 private_client = calloc(1, sizeof *private_client);
100 if (!private_client) {
101 TDM_ERR("alloc failed");
103 *error = TDM_CLIENT_ERROR_OUT_OF_MEMORY;
107 private_client->display = wl_display_connect("tdm-socket");
108 TDM_GOTO_IF_FAIL(private_client->display != NULL, create_failed);
110 private_client->registry = wl_display_get_registry(private_client->display);
111 TDM_GOTO_IF_FAIL(private_client->registry != NULL, create_failed);
113 wl_registry_add_listener(private_client->registry,
114 &tdm_client_registry_listener, private_client);
115 wl_display_roundtrip(private_client->display);
117 /* check global objects */
118 TDM_GOTO_IF_FAIL(private_client->tdm != NULL, create_failed);
120 LIST_INITHEAD(&private_client->vblank_list);
123 *error = TDM_CLIENT_ERROR_NONE;
125 return (tdm_client*)private_client;
127 tdm_client_destroy((tdm_client*)private_client);
129 *error = TDM_CLIENT_ERROR_OPERATION_FAILED;
134 tdm_client_destroy(tdm_client *client)
136 tdm_private_client *private_client = (tdm_private_client*)client;
137 tdm_client_vblank_info *v = NULL, *vv = NULL;
142 LIST_FOR_EACH_ENTRY_SAFE(v, vv, &private_client->vblank_list, link) {
144 wl_tdm_vblank_destroy(v->vblank);
148 if (private_client->tdm)
149 wl_tdm_destroy(private_client->tdm);
150 if (private_client->registry)
151 wl_registry_destroy(private_client->registry);
152 if (private_client->display)
153 wl_display_disconnect(private_client->display);
155 free(private_client);
159 tdm_client_get_fd(tdm_client *client, int *fd)
161 tdm_private_client *private_client;
163 TDM_RETURN_VAL_IF_FAIL(client != NULL, TDM_CLIENT_ERROR_INVALID_PARAMETER);
164 TDM_RETURN_VAL_IF_FAIL(fd != NULL, TDM_CLIENT_ERROR_INVALID_PARAMETER);
166 private_client = (tdm_private_client*)client;
168 *fd = wl_display_get_fd(private_client->display);
170 return TDM_CLIENT_ERROR_OPERATION_FAILED;
172 return TDM_CLIENT_ERROR_NONE;
176 tdm_client_handle_events(tdm_client *client)
178 tdm_private_client *private_client;
180 TDM_RETURN_VAL_IF_FAIL(client != NULL, TDM_CLIENT_ERROR_INVALID_PARAMETER);
182 private_client = (tdm_private_client*)client;
184 wl_display_dispatch(private_client->display);
186 return TDM_CLIENT_ERROR_NONE;
190 _tdm_client_cb_vblank_done(void *data, struct wl_tdm_vblank *vblank,
191 uint32_t sequence, uint32_t tv_sec, uint32_t tv_usec)
193 tdm_client_vblank_info *vblank_info = (tdm_client_vblank_info*)data;
195 TDM_RETURN_IF_FAIL(vblank_info != NULL);
197 if (vblank_info->func) {
198 vblank_info->func(sequence, tv_sec, tv_usec, vblank_info->user_data);
201 LIST_DEL(&vblank_info->link);
205 static const struct wl_tdm_vblank_listener tdm_client_vblank_listener = {
206 _tdm_client_cb_vblank_done,
210 tdm_client_wait_vblank(tdm_client *client, char *name, int interval, int sync,
211 tdm_client_vblank_handler func, void *user_data)
213 tdm_private_client *private_client = (tdm_private_client*)client;
214 tdm_client_vblank_info *vblank_info;
216 TDM_RETURN_VAL_IF_FAIL(name != NULL, TDM_CLIENT_ERROR_INVALID_PARAMETER);
217 TDM_RETURN_VAL_IF_FAIL(interval > 0, TDM_CLIENT_ERROR_INVALID_PARAMETER);
218 TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_CLIENT_ERROR_INVALID_PARAMETER);
219 TDM_RETURN_VAL_IF_FAIL(private_client != NULL, TDM_CLIENT_ERROR_INVALID_PARAMETER);
220 TDM_RETURN_VAL_IF_FAIL(private_client->tdm != NULL, TDM_CLIENT_ERROR_INVALID_PARAMETER);
222 vblank_info = calloc(1, sizeof *vblank_info);
224 TDM_ERR("alloc failed");
225 return TDM_CLIENT_ERROR_OUT_OF_MEMORY;
228 vblank_info->vblank = wl_tdm_wait_vblank(private_client->tdm, name, interval);
229 if (!vblank_info->vblank) {
230 TDM_ERR("couldn't create vblank resource");
232 return TDM_CLIENT_ERROR_OUT_OF_MEMORY;
235 wl_tdm_vblank_add_listener(vblank_info->vblank,
236 &tdm_client_vblank_listener, vblank_info);
238 vblank_info->func = func;
239 vblank_info->user_data = user_data;
240 LIST_ADDTAIL(&vblank_info->link, &private_client->vblank_list);
243 wl_display_roundtrip(private_client->display);
245 wl_display_flush(private_client->display);
247 return TDM_CLIENT_ERROR_NONE;