062e392a54c983c19c654fed0dd976b22334d351
[platform/core/uifw/libtbm.git] / src / tbm_wayland.c
1 /**************************************************************************
2
3 libtbm
4
5 Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
6
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
8 Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
9
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
17
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
20 of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 **************************************************************************/
31
32 #include "config.h"
33
34 #include "tbm_bufmgr_int.h"
35 #include <xf86drm.h>
36
37 #include <stdint.h>
38 #include <stddef.h>
39 #include "wayland-client.h"
40
41 struct wl_client;
42 struct wl_resource;
43
44 struct wl_drm;
45
46 #ifndef WL_DRM_ERROR_ENUM
47 #define WL_DRM_ERROR_ENUM
48 enum wl_drm_error {
49         WL_DRM_ERROR_AUTHENTICATE_FAIL = 0,
50         WL_DRM_ERROR_INVALID_FORMAT = 1,
51         WL_DRM_ERROR_INVALID_NAME = 2,
52 };
53 #endif /* WL_DRM_ERROR_ENUM */
54
55
56 #ifndef WL_DRM_CAPABILITY_ENUM
57 #define WL_DRM_CAPABILITY_ENUM
58 /**
59  * wl_drm_capability - wl_drm capability bitmask
60  * @WL_DRM_CAPABILITY_PRIME: wl_drm prime available
61  *
62  * Bitmask of capabilities.
63  */
64 enum wl_drm_capability {
65         WL_DRM_CAPABILITY_PRIME = 1,
66 };
67 #endif /* WL_DRM_CAPABILITY_ENUM */
68
69 struct wl_drm_listener {
70         /**
71          * device - (none)
72          * @name: (none)
73          */
74         void (*device)(void *data,
75                        struct wl_drm *wl_drm,
76                        const char *name);
77         /**
78          * format - (none)
79          * @format: (none)
80          */
81         void (*format)(void *data,
82                        struct wl_drm *wl_drm,
83                        uint32_t format);
84         /**
85          * authenticated - (none)
86          */
87         void (*authenticated)(void *data,
88                               struct wl_drm *wl_drm);
89         /**
90          * capabilities - (none)
91          * @value: (none)
92          */
93         void (*capabilities)(void *data,
94                              struct wl_drm *wl_drm,
95                              uint32_t value);
96 };
97
98 static inline int
99 wl_drm_add_listener(struct wl_drm *wl_drm,
100                     const struct wl_drm_listener *listener, void *data)
101 {
102         return wl_proxy_add_listener((struct wl_proxy *) wl_drm,
103                                      (void (**)(void)) listener, data);
104 }
105
106 #define WL_DRM_AUTHENTICATE     0
107
108 static inline void
109 wl_drm_destroy(struct wl_drm *wl_drm)
110 {
111         wl_proxy_destroy((struct wl_proxy *) wl_drm);
112 }
113
114 static inline void
115 wl_drm_authenticate(struct wl_drm *wl_drm, uint32_t id)
116 {
117         wl_proxy_marshal((struct wl_proxy *) wl_drm,
118                          WL_DRM_AUTHENTICATE, id);
119 }
120
121 static const struct wl_interface *types[] = {
122         NULL,
123         &wl_buffer_interface,
124         NULL,
125         NULL,
126         NULL,
127         NULL,
128         NULL,
129         &wl_buffer_interface,
130         NULL,
131         NULL,
132         NULL,
133         NULL,
134         NULL,
135         NULL,
136         NULL,
137         NULL,
138         NULL,
139         NULL,
140         &wl_buffer_interface,
141         NULL,
142         NULL,
143         NULL,
144         NULL,
145         NULL,
146         NULL,
147         NULL,
148         NULL,
149         NULL,
150         NULL,
151 };
152
153 static const struct wl_message wl_drm_requests[] = {
154         { "authenticate", "u", types + 0 },
155         { "create_buffer", "nuiiuu", types + 1 },
156         { "create_planar_buffer", "nuiiuiiiiii", types + 7 },
157         { "create_prime_buffer", "2nhiiuiiiiii", types + 18 },
158 };
159
160 static const struct wl_message wl_drm_events[] = {
161         { "device", "s", types + 0 },
162         { "format", "u", types + 0 },
163         { "authenticated", "", types + 0 },
164         { "capabilities", "u", types + 0 },
165 };
166
167 static const struct wl_interface wl_drm_interface = {
168         "wl_drm", 2,
169         4, wl_drm_requests,
170         4, wl_drm_events,
171 };
172
173 #define USE_QUEUE 1
174
175 struct wl_drm_info {
176 #if USE_QUEUE
177    struct wl_event_queue *wl_queue;
178 #endif   
179    struct wl_drm* wl_drm;
180    int authenticated;
181    int fd;
182 };
183
184 static void wl_client_drm_handle_device(void *data, struct wl_drm *drm, const char *device)
185 {
186     struct wl_drm_info *drm_info = (struct wl_drm_info *)data;
187     drm_magic_t magic;
188
189     printf("device[%s]\n", device);
190     drm_info->fd = open(device, O_RDWR | O_CLOEXEC);
191     if (drm_info->fd < 0) {
192         printf("Failed to open a device: %d (%s)\n", errno, device);
193         return;
194     }
195
196     drmGetMagic(drm_info->fd, &magic);
197     printf("magic[%x]\n", magic);
198     wl_drm_authenticate(drm_info->wl_drm, magic);
199 }
200
201 static void wl_client_drm_handle_format(void *data, struct wl_drm *drm, uint32_t format)
202 {
203     /* Do nothing */
204 }
205
206 static void wl_client_drm_handle_authenticated(void *data, struct wl_drm *drm)
207 {
208     struct wl_drm_info *drm_info = (struct wl_drm_info *)data;
209     drm_info->authenticated = 1;
210 }
211
212 static void wl_client_drm_handle_capabilities(void *data, struct wl_drm *drm, uint32_t value)
213 {
214     /* Do nothing */
215 }
216
217  
218
219 static void wl_client_registry_handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version)
220 {
221     struct wl_drm_info *info = (struct wl_drm_info *)data;
222     static const struct wl_drm_listener wl_drm_client_listener = {
223         wl_client_drm_handle_device,
224         wl_client_drm_handle_format,
225         wl_client_drm_handle_authenticated,
226         wl_client_drm_handle_capabilities
227     };
228
229     printf("interface[%s]\n", interface);
230     if (!strcmp(interface, "wl_drm")) {
231         info->wl_drm = wl_registry_bind(registry, name, &wl_drm_interface, (version > 2) ? 2 : version);
232 #if USE_QUEUE        
233         wl_proxy_set_queue((struct wl_proxy *)info->wl_drm, info->wl_queue);
234 #endif        
235         wl_drm_add_listener(info->wl_drm, &wl_drm_client_listener, data);
236     }
237 }
238
239 static int tbm_util_get_drm_fd(void *dpy, int *fd)
240 {
241     struct wl_display *disp = NULL;
242     struct wl_registry *wl_registry;
243     int ret = 0;
244     struct wl_drm_info info = {
245 #if USE_QUEUE    
246         .wl_queue = NULL,
247 #endif
248         .wl_drm = NULL,
249         .authenticated = 0,
250         .fd = -1,
251     };
252     static const struct wl_registry_listener registry_listener = {
253         wl_client_registry_handle_global,
254         NULL
255     };
256
257     if (!fd) {
258         return -1;
259     }
260
261     if (!dpy) {
262         disp = wl_display_connect(NULL);
263         if (!disp) {
264             printf("Failed to create a new display connection\n");
265             return -1;
266         }
267         dpy = disp;
268     }
269     
270 #if USE_QUEUE
271     info.wl_queue = wl_display_create_queue(dpy);
272     if (!info.wl_queue) {
273         printf("Failed to create a WL Queue\n");
274         if (disp == dpy) {
275             wl_display_disconnect(disp);
276         }
277         return -1;
278     }
279 #endif
280     wl_registry = wl_display_get_registry(dpy);
281     if (!wl_registry) {
282         printf("Failed to get registry\n");
283 #if USE_QUEUE        
284         wl_event_queue_destroy(info.wl_queue);
285 #endif
286         if (disp == dpy) {
287             wl_display_disconnect(disp);
288         }
289         return -1;
290     }
291 #if USE_QUEUE
292     wl_proxy_set_queue((struct wl_proxy *)wl_registry, info.wl_queue);
293 #endif
294     wl_registry_add_listener(wl_registry, &registry_listener, &info); 
295     wl_display_roundtrip(dpy);
296     
297     printf("Consuming Dispatch Queue begin\n");
298     while (ret != -1 && !info.authenticated) {
299 #if USE_QUEUE
300         ret = wl_display_dispatch_queue(dpy, info.wl_queue);
301 #else
302         ret = wl_display_dispatch(dpy);
303 #endif
304         printf("Dispatch Queue consumed: %d\n", ret);
305     }
306     printf("Consuming Dispatch Queue end\n");
307     
308 #if USE_QUEUE
309     wl_event_queue_destroy(info.wl_queue);
310 #endif    
311     wl_registry_destroy(wl_registry);
312     wl_drm_destroy(info.wl_drm);
313
314     *fd = info.fd;
315     if (disp == dpy) {
316         wl_display_disconnect(disp);
317     }
318     return *fd >= 0 ? 0 : -1;
319 }
320
321 int
322 tbm_bufmgr_get_drm_fd_wayland()
323 {
324     int fd = -1;
325     
326     if(tbm_util_get_drm_fd(NULL, &fd))
327     {
328         printf("Failed to get drm_fd\n");
329     }
330     
331     return fd;
332 }