• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright (C) 2013 DENSO CORPORATION
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  ****************************************************************************/
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <memory.h>
22 #include <unistd.h>
23 #include <signal.h>
24 #include <poll.h>
25 #include "ilm_client.h"
26 #include "ilm_client_platform.h"
27 #include "wayland-util.h"
28 #include "ivi-application-client-protocol.h"
29 static ilmErrorTypes wayland_surfaceCreate(t_ilm_nativehandle nativehandle,
30                          t_ilm_int width, t_ilm_int height,
31                          ilmPixelFormat pixelFormat,
32                          t_ilm_surface* pSurfaceId);
33 static ilmErrorTypes wayland_surfaceRemove(const t_ilm_surface surfaceId);
34 static ilmErrorTypes wayland_init(t_ilm_nativedisplay nativedisplay);
35 static ilmErrorTypes wayland_destroy(void);
36 
37 ILM_CLIENT_PLATFORM_FUNC gIlmClientPlatformFunc;
38 
init_ilmClientPlatformTable(void)39 void init_ilmClientPlatformTable(void)
40 {
41     gIlmClientPlatformFunc.surfaceCreate =
42         wayland_surfaceCreate;
43     gIlmClientPlatformFunc.surfaceRemove =
44         wayland_surfaceRemove;
45     gIlmClientPlatformFunc.init =
46         wayland_init;
47     gIlmClientPlatformFunc.destroy =
48         wayland_destroy;
49 }
50 
51 struct surface_context {
52     struct ivi_surface *surface;
53     t_ilm_uint id_surface;
54     struct ilmSurfaceProperties prop;
55 
56     struct wl_list link;
57 };
58 
59 struct ilm_client_context {
60     int32_t valid;
61     struct wl_display *display;
62     struct wl_registry *registry;
63     struct wl_compositor *compositor;
64     struct ivi_application *ivi_application;
65     struct wl_event_queue *queue;
66 
67     struct wl_list list_surface;
68 
69     uint32_t internal_id_surface;
70     uint32_t name_controller;
71 };
72 
73 static void
wayland_client_init(struct ilm_client_context * ctx)74 wayland_client_init(struct ilm_client_context *ctx)
75 {
76     ctx->internal_id_surface = 0;
77 }
78 
79 static uint32_t
wayland_client_gen_surface_id(struct ilm_client_context * ctx)80 wayland_client_gen_surface_id(struct ilm_client_context *ctx)
81 {
82     struct surface_context *ctx_surf = NULL;
83     do {
84         int found = 0;
85         if (wl_list_length(&ctx->list_surface) == 0) {
86             ctx->internal_id_surface++;
87             return ctx->internal_id_surface;
88         }
89         wl_list_for_each(ctx_surf, &ctx->list_surface, link) {
90             if (ctx_surf->id_surface == ctx->internal_id_surface) {
91                 found = 1;
92                 break;
93             }
94 
95             if (found == 0) {
96                 return ctx->internal_id_surface;
97             }
98         }
99         ctx->internal_id_surface++;
100     } while(1);
101 }
102 
103 static void
registry_handle_client(void * data,struct wl_registry * registry,uint32_t name,const char * interface,uint32_t version)104 registry_handle_client(void *data, struct wl_registry *registry,
105                        uint32_t name, const char *interface,
106                        uint32_t version)
107 {
108     struct ilm_client_context *ctx = data;
109     (void)version;
110 
111     if (strcmp(interface, "ivi_application") == 0) {
112         ctx->ivi_application = wl_registry_bind(registry, name,
113                                            &ivi_application_interface, 1);
114         if (ctx->ivi_application == NULL) {
115             fprintf(stderr, "Failed to registry bind ivi_application\n");
116             return;
117         }
118     }
119 }
120 
121 static void
registry_handle_client_remove(void * data,struct wl_registry * registry,uint32_t name)122 registry_handle_client_remove(void *data, struct wl_registry *registry, uint32_t name)
123 {
124 }
125 
126 static const struct wl_registry_listener registry_client_listener = {
127     registry_handle_client,
128     registry_handle_client_remove
129 };
130 
131 static struct ilm_client_context ilm_context = {0};
132 
133 static void
134 destroy_client_resouses(void);
135 
136 static ilmErrorTypes
wayland_destroy(void)137 wayland_destroy(void)
138 {
139     struct ilm_client_context *ctx = &ilm_context;
140     if (ctx->valid)
141     {
142         destroy_client_resouses();
143         ctx->valid = 0;
144 
145     }
146 
147     return ILM_SUCCESS;
148 }
149 
150 static void
destroy_client_resouses(void)151 destroy_client_resouses(void)
152 {
153     struct ilm_client_context *ctx = &ilm_context;
154 
155     {
156         struct surface_context *c = NULL;
157         struct surface_context *n = NULL;
158         wl_list_for_each_safe(c, n, &ctx->list_surface, link) {
159             wl_list_remove(&c->link);
160             ivi_surface_destroy(c->surface);
161             free(c);
162         }
163     }
164 
165     if (ctx->ivi_application != NULL) {
166         ivi_application_destroy(ctx->ivi_application);
167         ctx->ivi_application = NULL;
168     }
169 
170     if (ctx->queue)
171     {
172         wl_event_queue_destroy(ctx->queue);
173         ctx->queue = NULL;
174     }
175 
176     if (ctx->registry)
177     {
178         wl_registry_destroy(ctx->registry);
179         ctx->registry = NULL;
180     }
181 }
182 
183 static ilmErrorTypes
wayland_init(t_ilm_nativedisplay nativedisplay)184 wayland_init(t_ilm_nativedisplay nativedisplay)
185 {
186     struct ilm_client_context *ctx = &ilm_context;
187     memset(ctx, 0, sizeof *ctx);
188 
189     wayland_client_init(ctx);
190     ctx->display = (struct wl_display*)nativedisplay;
191 
192     return ILM_SUCCESS;
193 }
194 
195 static void
init_client(void)196 init_client(void)
197 {
198     struct ilm_client_context *ctx = &ilm_context;
199 
200     if (ctx->display == NULL) {
201 	ctx->display = wl_display_connect(NULL);
202     }
203 
204     wl_list_init(&ctx->list_surface);
205 
206     ctx->queue = wl_display_create_queue(ctx->display);
207     ctx->registry = wl_display_get_registry(ctx->display);
208     if (ctx->registry == NULL) {
209         wl_event_queue_destroy(ctx->queue);
210         fprintf(stderr, "Failed to get registry\n");
211         return;
212     }
213 
214     wl_proxy_set_queue((void*)ctx->registry, ctx->queue);
215     if (wl_registry_add_listener(ctx->registry,
216                              &registry_client_listener, ctx)) {
217         fprintf(stderr, "Failed to add registry listener\n");
218         return;
219     }
220     wl_display_roundtrip_queue(ctx->display, ctx->queue);
221 
222     if ((ctx->display == NULL) || (ctx->ivi_application == NULL)) {
223         fprintf(stderr, "Failed to connect display at ilm_client\n");
224         return;
225     }
226 
227     ctx->valid = 1;
228 }
229 
230 static struct ilm_client_context*
get_client_instance(void)231 get_client_instance(void)
232 {
233     struct ilm_client_context *ctx = &ilm_context;
234     if (ctx->valid == 0) {
235         init_client();
236     }
237 
238     if (ctx->valid < 0) {
239         exit(0);
240     }
241 
242     wl_display_roundtrip_queue(ctx->display, ctx->queue);
243 
244     return ctx;
245 }
246 
247 static void
create_client_surface(struct ilm_client_context * ctx,uint32_t id_surface,struct ivi_surface * surface)248 create_client_surface(struct ilm_client_context *ctx,
249                       uint32_t id_surface,
250                       struct ivi_surface *surface)
251 {
252     struct surface_context *ctx_surf = NULL;
253 
254     ctx_surf = calloc(1, sizeof *ctx_surf);
255     if (ctx_surf == NULL) {
256         fprintf(stderr, "Failed to allocate memory for surface_context\n");
257         return;
258     }
259 
260     ctx_surf->surface = surface;
261     ctx_surf->id_surface = id_surface;
262     wl_list_insert(&ctx->list_surface, &ctx_surf->link);
263 }
264 
265 static ilmErrorTypes
wayland_surfaceCreate(t_ilm_nativehandle nativehandle,t_ilm_int width,t_ilm_int height,ilmPixelFormat pixelFormat,t_ilm_surface * pSurfaceId)266 wayland_surfaceCreate(t_ilm_nativehandle nativehandle,
267                       t_ilm_int width,
268                       t_ilm_int height,
269                       ilmPixelFormat pixelFormat,
270                       t_ilm_surface* pSurfaceId)
271 {
272     ilmErrorTypes returnValue = ILM_FAILED;
273     struct ilm_client_context *ctx = get_client_instance();
274     uint32_t surfaceid = 0;
275     struct ivi_surface *surf = NULL;
276     (void)pixelFormat;
277     (void)width;
278     (void)height;
279 
280     if (nativehandle == 0) {
281         return returnValue;
282     }
283 
284     if (pSurfaceId != NULL) {
285         if (*pSurfaceId == INVALID_ID) {
286             surfaceid =
287                 wayland_client_gen_surface_id(ctx);
288         }
289         else {
290             surfaceid = *pSurfaceId;
291         }
292 
293         surf = ivi_application_surface_create(ctx->ivi_application, surfaceid,
294                                          (struct wl_surface*)nativehandle);
295 
296         if (surf != NULL) {
297             create_client_surface(ctx, surfaceid, surf);
298             *pSurfaceId = surfaceid;
299             returnValue = ILM_SUCCESS;
300         }
301         else {
302             fprintf(stderr, "Failed to create ivi_surface\n");
303         }
304     }
305 
306     return returnValue;
307 }
308 
309 static ilmErrorTypes
wayland_surfaceRemove(t_ilm_surface surfaceId)310 wayland_surfaceRemove(t_ilm_surface surfaceId)
311 {
312     struct ilm_client_context *ctx = get_client_instance();
313     struct surface_context *ctx_surf = NULL;
314     struct surface_context *ctx_next = NULL;
315 
316     wl_list_for_each_safe(ctx_surf, ctx_next,
317                           &ctx->list_surface,
318                           link) {
319         if (ctx_surf->id_surface == surfaceId) {
320             ivi_surface_destroy(ctx_surf->surface);
321             wl_list_remove(&ctx_surf->link);
322             free(ctx_surf);
323             break;
324         }
325     }
326 
327     return ILM_SUCCESS;
328 }
329