v1.2.0
[platform/adaptation/renesas_rcar/wayland-kms.git] / wayland-kms-auth.c
1 /*
2  * Copyright © 2013 Renesas Solutions Corp.
3  * Copyright © 2011 Kristian Høgsberg
4  * Copyright © 2011 Benjamin Franzke
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24  * DEALINGS IN THE SOFTWARE.
25  *
26  * Authors:
27  *    Takanari Hayama <taki@igel.co.jp>
28  *
29  * Based on wayland-drm.c by the following authors:
30  *    Kristian Høgsberg <krh@bitplanet.net>
31  *    Benjamin Franzke <benjaminfranzke@googlemail.com>
32  */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stddef.h>
38 #include <unistd.h>
39 #include <errno.h>
40
41 #include <xf86drm.h>
42 #include <wayland-client.h>
43 #include "wayland-kms-auth.h"
44 #include "wayland-kms-client-protocol.h"
45
46 #if defined(DEBUG)
47 #       define WLKMS_DEBUG(s, x...) { printf(s, ##x); }
48 #else
49 #       define WLKMS_DEBUG(s, x...) { }
50 #endif
51
52 struct kms_auth {
53         struct wl_display *wl_display;  /* wl_display facing my server */
54         struct wl_event_queue *wl_queue;
55         struct wl_registry *wl_registry;
56         struct wl_kms *wl_kms;
57         int authenticated;
58 };
59
60
61 /*
62  * Sync with the server
63  */
64
65 static void wayland_sync_callback(void *data, struct wl_callback *callback, uint32_t serial)
66 {
67         int *done = data;
68         *done = 1;
69         WLKMS_DEBUG("%s: %s: %d\n", __FILE__, __func__, __LINE__);
70         wl_callback_destroy(callback);
71 }
72
73 static const struct wl_callback_listener wayland_sync_listener = {
74         .done = wayland_sync_callback
75 };
76
77 /*
78  * sync with the server
79  */
80 int wayland_sync(struct kms_auth *auth)
81 {
82         struct wl_callback *callback;
83         int ret = 0, done = 0;
84
85         WLKMS_DEBUG("%s: %s: %d\n", __FILE__, __func__, __LINE__);
86         callback = wl_display_sync(auth->wl_display);
87         wl_callback_add_listener(callback, &wayland_sync_listener, &done);
88         wl_proxy_set_queue((struct wl_proxy*)callback, auth->wl_queue);
89         while (ret >= 0 && !done) {
90                 ret = wl_display_dispatch_queue(auth->wl_display, auth->wl_queue);
91         }
92
93         if (!done) {
94                 wl_callback_destroy(callback);
95         }
96
97         return ret;
98 }
99
100 /*
101  * For the nested authentication
102  */
103
104 static void wayland_kms_handle_authenticated(void *data, struct wl_kms *kms)
105 {
106         struct kms_auth *auth = data;
107         WLKMS_DEBUG("%s: %s: %d: authenticated.\n", __FILE__, __func__, __LINE__);
108         auth->authenticated = 1;
109 }
110
111 static void wayland_kms_handle_format(void *data, struct wl_kms *kms, uint32_t format)
112 {
113 }
114
115 static void wayland_kms_handle_device(void *data, struct wl_kms *kms, const char *device)
116 {
117 }
118
119 static const struct wl_kms_listener wayland_kms_listener = {
120         .authenticated = wayland_kms_handle_authenticated,
121         .format = wayland_kms_handle_format,
122         .device = wayland_kms_handle_device
123 };
124
125 /*
126  * registry routines to the server global objects
127  */
128
129 static void wayland_registry_handle_global(void *data, struct wl_registry *registry,
130                                                            uint32_t name, const char *interface, uint32_t version)
131 {
132         struct kms_auth *auth = data;
133
134         WLKMS_DEBUG("%s: %s: %d\n", __FILE__, __func__, __LINE__);
135
136         /*
137          * we need to connect to the wl_kms objects
138          */
139         if (!strcmp(interface, "wl_kms")) {
140                 auth->wl_kms = wl_registry_bind(registry, name, &wl_kms_interface, version);
141                 wl_kms_add_listener(auth->wl_kms, &wayland_kms_listener, auth);
142         }
143 }
144
145 static void wayland_registry_handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
146 {
147 }
148
149 static const struct wl_registry_listener wayland_registry_listener = {
150         .global = wayland_registry_handle_global,
151         .global_remove = wayland_registry_handle_global_remove,
152 };
153
154 int
155 kms_auth_request(struct kms_auth *auth, uint32_t magic)
156 {
157         auth->authenticated = 0;
158         wl_kms_authenticate(auth->wl_kms, magic);
159
160         if (wayland_sync(auth) < 0 || !auth->authenticated)
161                 return -1;
162
163         return 0;
164 }
165
166 struct kms_auth*
167 kms_auth_init(struct wl_display *display)
168 {
169         struct kms_auth *auth;
170
171         if (!(auth = calloc(1, sizeof(struct kms_auth))))
172                 return NULL;
173
174         auth->wl_display = display;
175
176         auth->wl_queue = wl_display_create_queue(auth->wl_display);
177         auth->wl_registry = wl_display_get_registry(auth->wl_display);
178         wl_proxy_set_queue((struct wl_proxy*)auth->wl_registry, auth->wl_queue);
179         wl_registry_add_listener(auth->wl_registry, &wayland_registry_listener, auth);
180
181         if (wayland_sync(auth) < 0) {
182                 free(auth);
183                 return NULL;
184         }
185
186         return auth;
187 }