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 destroy_client_resouses(void);
259 wayland_destroy(void)
261 struct ilm_client_context *ctx = &ilm_context;
264 destroy_client_resouses();
270 destroy_client_resouses(void)
272 struct ilm_client_context *ctx = &ilm_context;
275 struct surface_context *c = NULL;
276 struct surface_context *n = NULL;
277 wl_list_for_each_safe(c, n, &ctx->list_surface, link) {
278 wl_list_remove(&c->link);
279 ivi_surface_destroy(c->surface);
285 struct screen_context *ctx_scrn = NULL;
286 struct screen_context *next = NULL;
287 wl_list_for_each_safe(ctx_scrn, next, &ctx->list_screen, link) {
288 if (ctx_scrn->output != NULL) {
289 wl_output_destroy(ctx_scrn->output);
292 wl_list_remove(&ctx_scrn->link);
297 if (ctx->ivi_application != NULL) {
298 ivi_application_destroy(ctx->ivi_application);
299 ctx->ivi_application = NULL;
304 wl_registry_destroy(ctx->registry);
305 ctx->registry = NULL;
310 wayland_init(t_ilm_nativedisplay nativedisplay)
312 struct ilm_client_context *ctx = &ilm_context;
313 memset(ctx, 0, sizeof *ctx);
315 wayland_client_init(ctx);
316 ctx->display = (struct wl_display*)nativedisplay;
324 struct ilm_client_context *ctx = &ilm_context;
326 if (ctx->display == NULL) {
327 ctx->display = wl_display_connect(NULL);
332 wl_list_init(&ctx->list_screen);
333 wl_list_init(&ctx->list_surface);
335 ctx->registry = wl_display_get_registry(ctx->display);
336 if (ctx->registry == NULL) {
337 fprintf(stderr, "Failed to get registry\n");
340 if (wl_registry_add_listener(ctx->registry,
341 ®istry_client_listener, ctx)) {
342 fprintf(stderr, "Failed to add registry listener\n");
345 wl_display_dispatch(ctx->display);
346 wl_display_roundtrip(ctx->display);
348 if ((ctx->display == NULL) || (ctx->ivi_application == NULL)) {
349 fprintf(stderr, "Failed to connect display at ilm_client\n");
355 static struct ilm_client_context*
356 get_client_instance(void)
358 struct ilm_client_context *ctx = &ilm_context;
359 if (ctx->valid == 0) {
363 if (ctx->valid < 0) {
367 wl_display_roundtrip(ctx->display);
373 create_client_surface(struct ilm_client_context *ctx,
375 struct ivi_surface *surface)
377 struct surface_context *ctx_surf = NULL;
379 ctx_surf = calloc(1, sizeof *ctx_surf);
380 if (ctx_surf == NULL) {
381 fprintf(stderr, "Failed to allocate memory for surface_context\n");
385 ctx_surf->surface = surface;
386 ctx_surf->id_surface = id_surface;
387 wl_list_init(&ctx_surf->link);
388 wl_list_insert(&ctx->list_surface, &ctx_surf->link);
391 static struct surface_context*
392 get_surface_context_by_id(struct ilm_client_context *ctx,
395 struct surface_context *ctx_surf = NULL;
397 wl_list_for_each(ctx_surf, &ctx->list_surface, link) {
398 if (ctx_surf->id_surface == id_surface) {
407 wayland_getScreenResolution(t_ilm_uint screenID,
411 ilmErrorTypes returnValue = ILM_FAILED;
412 struct ilm_client_context *ctx = get_client_instance();
414 if ((pWidth != NULL) && (pHeight != NULL))
416 struct screen_context *ctx_scrn;
417 wl_list_for_each(ctx_scrn, &ctx->list_screen, link) {
418 if (screenID == ctx_scrn->id_screen) {
419 *pWidth = ctx_scrn->width;
420 *pHeight = ctx_scrn->height;
421 returnValue = ILM_SUCCESS;
431 wayland_surfaceCreate(t_ilm_nativehandle nativehandle,
434 ilmPixelFormat pixelFormat,
435 t_ilm_surface* pSurfaceId)
437 ilmErrorTypes returnValue = ILM_FAILED;
438 struct ilm_client_context *ctx = get_client_instance();
439 uint32_t surfaceid = 0;
440 struct ivi_surface *surf = NULL;
445 if (nativehandle == 0) {
449 if (pSurfaceId != NULL) {
450 if (*pSurfaceId == INVALID_ID) {
452 wayland_client_gen_surface_id(ctx);
455 surfaceid = *pSurfaceId;
458 surf = ivi_application_surface_create(ctx->ivi_application, surfaceid,
459 (struct wl_surface*)nativehandle);
462 create_client_surface(ctx, surfaceid, surf);
463 *pSurfaceId = surfaceid;
464 returnValue = ILM_SUCCESS;
467 fprintf(stderr, "Failed to create ivi_surface\n");
475 wayland_surfaceRemove(t_ilm_surface surfaceId)
477 struct ilm_client_context *ctx = get_client_instance();
478 struct surface_context *ctx_surf = NULL;
479 struct surface_context *ctx_next = NULL;
481 wl_list_for_each_safe(ctx_surf, ctx_next,
484 if (ctx_surf->id_surface == surfaceId) {
485 ivi_surface_destroy(ctx_surf->surface);
486 wl_list_remove(&ctx_surf->link);
496 wayland_surfaceRemoveNativeContent(t_ilm_surface surfaceId)
500 /* There is no API to set native content
501 as such ivi_surface_set_native. */
506 wayland_surfaceSetNativeContent(t_ilm_nativehandle nativehandle,
509 ilmPixelFormat pixelFormat,
510 t_ilm_surface surfaceId)
518 /* There is no API to set native content
519 as such ivi_surface_set_native. */
524 wayland_UpdateInputEventAcceptanceOn(t_ilm_surface surfaceId,
525 ilmInputDevice devices,
526 t_ilm_bool acceptance)
528 ilmErrorTypes returnValue = ILM_FAILED;
529 struct ilm_client_context *ctx = get_client_instance();
530 struct surface_context *ctx_surf = NULL;
532 ctx_surf = get_surface_context_by_id(ctx, (uint32_t)surfaceId);
534 if (ctx_surf != NULL) {
535 if (acceptance == ILM_TRUE) {
536 ctx_surf->prop.inputDevicesAcceptance = devices;
538 ctx_surf->prop.inputDevicesAcceptance &= ~devices;
540 returnValue = ILM_SUCCESS;
547 wayland_surfaceInitialize(t_ilm_surface *pSurfaceId)
549 ilmErrorTypes returnValue = ILM_FAILED;
551 returnValue = wayland_surfaceCreate((t_ilm_nativehandle)NULL,
552 100, 100, (ilmPixelFormat)NULL,
553 (t_ilm_surface*)pSurfaceId);