1 /**************************************************************************
3 * Copyright (C) 2013 DENSO CORPORATION
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ****************************************************************************/
25 #include "ilm_client.h"
26 #include "ilm_client_platform.h"
27 #include "wayland-util.h"
28 #include "ivi-application-client-protocol.h"
30 static ilmErrorTypes wayland_getScreenResolution(t_ilm_uint screenID,
31 t_ilm_uint* pWidth, t_ilm_uint* pHeight);
32 static ilmErrorTypes wayland_surfaceCreate(t_ilm_nativehandle nativehandle,
33 t_ilm_int width, t_ilm_int height,
34 ilmPixelFormat pixelFormat,
35 t_ilm_surface* pSurfaceId);
36 static ilmErrorTypes wayland_surfaceRemove(const t_ilm_surface surfaceId);
37 static ilmErrorTypes wayland_surfaceRemoveNativeContent(
38 t_ilm_surface surfaceId);
39 static ilmErrorTypes wayland_surfaceSetNativeContent(
40 t_ilm_nativehandle nativehandle,
41 t_ilm_int width, t_ilm_int height,
42 ilmPixelFormat pixelFormat,
43 t_ilm_surface surfaceId);
44 static ilmErrorTypes wayland_UpdateInputEventAcceptanceOn(
45 t_ilm_surface surfaceId,
46 ilmInputDevice devices,
47 t_ilm_bool acceptance);
48 static ilmErrorTypes wayland_init(t_ilm_nativedisplay nativedisplay);
49 static void wayland_destroy(void);
50 static ilmErrorTypes wayland_surfaceInitialize(t_ilm_surface *pSurfaceId);
52 void init_ilmClientPlatformTable(void)
54 gIlmClientPlatformFunc.getScreenResolution =
55 wayland_getScreenResolution;
56 gIlmClientPlatformFunc.surfaceCreate =
57 wayland_surfaceCreate;
58 gIlmClientPlatformFunc.surfaceRemove =
59 wayland_surfaceRemove;
60 gIlmClientPlatformFunc.surfaceRemoveNativeContent =
61 wayland_surfaceRemoveNativeContent;
62 gIlmClientPlatformFunc.surfaceSetNativeContent =
63 wayland_surfaceSetNativeContent;
64 gIlmClientPlatformFunc.UpdateInputEventAcceptanceOn =
65 wayland_UpdateInputEventAcceptanceOn;
66 gIlmClientPlatformFunc.init =
68 gIlmClientPlatformFunc.destroy =
70 gIlmClientPlatformFunc.surfaceInitialize =
71 wayland_surfaceInitialize;
74 struct surface_context {
75 struct ivi_surface *surface;
76 t_ilm_uint id_surface;
77 struct ilmSurfaceProperties prop;
82 struct screen_context {
83 struct wl_output *output;
92 struct ilm_client_context {
94 struct wl_display *display;
95 struct wl_registry *registry;
96 struct wl_compositor *compositor;
97 struct ivi_application *ivi_application;
100 struct wl_list list_surface;
101 struct wl_list list_screen;
103 uint32_t internal_id_surface;
104 uint32_t name_controller;
108 wayland_client_init(struct ilm_client_context *ctx)
110 ctx->internal_id_surface = 0;
114 wayland_client_gen_surface_id(struct ilm_client_context *ctx)
116 struct surface_context *ctx_surf = NULL;
119 if (wl_list_length(&ctx->list_surface) == 0) {
120 ctx->internal_id_surface++;
121 return ctx->internal_id_surface;
123 wl_list_for_each(ctx_surf, &ctx->list_surface, link) {
124 if (ctx_surf->id_surface == ctx->internal_id_surface) {
130 return ctx->internal_id_surface;
133 ctx->internal_id_surface++;
138 output_listener_geometry(void *data,
139 struct wl_output *wl_output,
142 int32_t physical_width,
143 int32_t physical_height,
149 struct screen_context *ctx_scrn = data;
158 ctx_scrn->width = physical_width;
159 ctx_scrn->height = physical_height;
163 output_listener_mode(void *data,
164 struct wl_output *wl_output,
179 output_listener_done(void *data,
180 struct wl_output *output)
187 output_listener_scale(void *data,
188 struct wl_output *output,
197 wl_output_listener output_listener = {
198 output_listener_geometry,
199 output_listener_mode,
200 output_listener_done,
201 output_listener_scale
205 registry_handle_client(void *data, struct wl_registry *registry,
206 uint32_t name, const char *interface,
209 struct ilm_client_context *ctx = data;
212 if (strcmp(interface, "ivi_application") == 0) {
213 ctx->ivi_application = wl_registry_bind(registry, name,
214 &ivi_application_interface, 1);
215 if (ctx->ivi_application == NULL) {
216 fprintf(stderr, "Failed to registry bind ivi_application\n");
219 } else if (strcmp(interface, "wl_output") == 0) {
220 struct screen_context *ctx_scrn = calloc(1, sizeof *ctx_scrn);
221 if (ctx_scrn == NULL) {
222 fprintf(stderr, "Failed to allocate memory for screen_context\n");
225 wl_list_init(&ctx_scrn->link);
226 ctx_scrn->output = wl_registry_bind(registry, name,
227 &wl_output_interface, 1);
228 if (ctx_scrn->output == NULL) {
230 fprintf(stderr, "Failed to registry bind wl_output\n");
234 if (wl_output_add_listener(ctx_scrn->output,
238 fprintf(stderr, "Failed to add wl_output listener\n");
242 ctx_scrn->id_screen = ctx->num_screen;
244 wl_list_insert(&ctx->list_screen, &ctx_scrn->link);
248 static const struct wl_registry_listener registry_client_listener = {
249 registry_handle_client,
253 static struct ilm_client_context ilm_context = {0};
256 wayland_destroy(void)
258 struct ilm_client_context *ctx = &ilm_context;
263 destroy_client_resouses(void)
265 struct ilm_client_context *ctx = &ilm_context;
266 struct screen_context *ctx_scrn = NULL;
267 struct screen_context *next = NULL;
268 wl_list_for_each_safe(ctx_scrn, next, &ctx->list_screen, link) {
269 if (ctx_scrn->output != NULL) {
270 wl_list_remove(&ctx_scrn->link);
271 wl_output_destroy(ctx_scrn->output);
275 if (ctx->ivi_application != NULL) {
276 ivi_application_destroy(ctx->ivi_application);
277 ctx->ivi_application = NULL;
282 wayland_init(t_ilm_nativedisplay nativedisplay)
284 struct ilm_client_context *ctx = &ilm_context;
285 memset(ctx, 0, sizeof *ctx);
287 wayland_client_init(ctx);
288 ctx->display = (struct wl_display*)nativedisplay;
296 struct ilm_client_context *ctx = &ilm_context;
298 if (ctx->display == NULL) {
299 ctx->display = wl_display_connect(NULL);
304 wl_list_init(&ctx->list_screen);
305 wl_list_init(&ctx->list_surface);
307 ctx->registry = wl_display_get_registry(ctx->display);
308 if (ctx->registry == NULL) {
309 fprintf(stderr, "Failed to get registry\n");
312 if (wl_registry_add_listener(ctx->registry,
313 ®istry_client_listener, ctx)) {
314 fprintf(stderr, "Failed to add registry listener\n");
317 wl_display_dispatch(ctx->display);
318 wl_display_roundtrip(ctx->display);
320 if ((ctx->display == NULL) || (ctx->ivi_application == NULL)) {
321 fprintf(stderr, "Failed to connect display at ilm_client\n");
327 static struct ilm_client_context*
328 get_client_instance(void)
330 struct ilm_client_context *ctx = &ilm_context;
331 if (ctx->valid == 0) {
335 if (ctx->valid < 0) {
339 wl_display_roundtrip(ctx->display);
345 create_client_surface(struct ilm_client_context *ctx,
347 struct ivi_surface *surface)
349 struct surface_context *ctx_surf = NULL;
351 ctx_surf = calloc(1, sizeof *ctx_surf);
352 if (ctx_surf == NULL) {
353 fprintf(stderr, "Failed to allocate memory for surface_context\n");
357 ctx_surf->surface = surface;
358 ctx_surf->id_surface = id_surface;
359 wl_list_init(&ctx_surf->link);
360 wl_list_insert(&ctx->list_surface, &ctx_surf->link);
363 static struct surface_context*
364 get_surface_context_by_id(struct ilm_client_context *ctx,
367 struct surface_context *ctx_surf = NULL;
369 wl_list_for_each(ctx_surf, &ctx->list_surface, link) {
370 if (ctx_surf->id_surface == id_surface) {
379 wayland_getScreenResolution(t_ilm_uint screenID,
383 ilmErrorTypes returnValue = ILM_FAILED;
384 struct ilm_client_context *ctx = get_client_instance();
386 if ((pWidth != NULL) && (pHeight != NULL))
388 struct screen_context *ctx_scrn;
389 wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
390 if (screenID == ctx_scrn->id_screen) {
391 *pWidth = ctx_scrn->width;
392 *pHeight = ctx_scrn->height;
393 returnValue = ILM_SUCCESS;
403 wayland_surfaceCreate(t_ilm_nativehandle nativehandle,
406 ilmPixelFormat pixelFormat,
407 t_ilm_surface* pSurfaceId)
409 ilmErrorTypes returnValue = ILM_FAILED;
410 struct ilm_client_context *ctx = get_client_instance();
411 uint32_t surfaceid = 0;
412 struct ivi_surface *surf = NULL;
417 if (nativehandle == 0) {
421 if (pSurfaceId != NULL) {
422 if (*pSurfaceId == INVALID_ID) {
424 wayland_client_gen_surface_id(ctx);
427 surfaceid = *pSurfaceId;
430 surf = ivi_application_surface_create(ctx->ivi_application, surfaceid,
431 (struct wl_surface*)nativehandle);
434 create_client_surface(ctx, surfaceid, surf);
435 *pSurfaceId = surfaceid;
436 returnValue = ILM_SUCCESS;
439 fprintf(stderr, "Failed to create ivi_surface\n");
447 wayland_surfaceRemove(t_ilm_surface surfaceId)
449 struct ilm_client_context *ctx = get_client_instance();
450 struct surface_context *ctx_surf = NULL;
451 struct surface_context *ctx_next = NULL;
453 wl_list_for_each_safe(ctx_surf, ctx_next,
456 if (ctx_surf->id_surface == surfaceId) {
457 ivi_surface_destroy(ctx_surf->surface);
458 wl_list_remove(&ctx_surf->link);
468 wayland_surfaceRemoveNativeContent(t_ilm_surface surfaceId)
472 /* There is no API to set native content
473 as such ivi_surface_set_native. */
478 wayland_surfaceSetNativeContent(t_ilm_nativehandle nativehandle,
481 ilmPixelFormat pixelFormat,
482 t_ilm_surface surfaceId)
490 /* There is no API to set native content
491 as such ivi_surface_set_native. */
496 wayland_UpdateInputEventAcceptanceOn(t_ilm_surface surfaceId,
497 ilmInputDevice devices,
498 t_ilm_bool acceptance)
500 ilmErrorTypes returnValue = ILM_FAILED;
501 struct ilm_client_context *ctx = get_client_instance();
502 struct surface_context *ctx_surf = NULL;
504 ctx_surf = get_surface_context_by_id(ctx, (uint32_t)surfaceId);
506 if (ctx_surf != NULL) {
507 if (acceptance == ILM_TRUE) {
508 ctx_surf->prop.inputDevicesAcceptance = devices;
510 ctx_surf->prop.inputDevicesAcceptance &= ~devices;
512 returnValue = ILM_SUCCESS;
519 wayland_surfaceInitialize(t_ilm_surface *pSurfaceId)
521 ilmErrorTypes returnValue = ILM_FAILED;
523 returnValue = wayland_surfaceCreate((t_ilm_nativehandle)NULL,
524 100, 100, (ilmPixelFormat)NULL,
525 (t_ilm_surface*)pSurfaceId);