4 #include <wayland-server.h>
5 #include <wtz-screen-server-protocol.h>
9 #include "libds-tizen/screen.h"
11 #define TIZEN_SCREEN_VERSION 1
13 struct ds_tizen_screen
15 struct wl_global *global;
17 struct wl_list clients;
19 struct wl_listener destroy;
21 struct wl_array capabilities;
23 uint32_t splitscreen_capability;
25 bool splitscreen_enabled;
28 struct wl_signal destroy;
29 struct wl_signal get_splitscreen;
33 struct ds_tizen_screen_client
35 struct ds_tizen_screen *screen;
37 struct wl_resource *resource;
38 struct wl_client *client;
41 struct wl_signal destroy;
44 struct wl_list link; // ds_tizen_screen::clients
47 struct ds_tizen_splitscreen
49 struct wl_resource *resource;
51 struct ds_tizen_screen_client *screen_client;
52 struct ds_tizen_screen *screen;
55 struct wl_signal destroy;
56 struct wl_signal activate;
57 struct wl_signal deactivate;
61 struct ds_tizen_splitscreen_region
63 struct wl_resource *resource;
68 struct wl_signal destroy;
69 struct wl_signal assign_appid;
74 splitscreen_handle_destroy(struct wl_client *client,
75 struct wl_resource *splitscreen_resource)
77 wl_resource_destroy(splitscreen_resource);
81 splitscreen_handle_activate(struct wl_client *client,
82 struct wl_resource *splitscreen_resource)
84 struct ds_tizen_splitscreen *splitscreen;
86 splitscreen = wl_resource_get_user_data(splitscreen_resource);
88 ds_inf("screen_splitscreen:%p activate", splitscreen);
90 wl_signal_emit(&splitscreen->events.activate, splitscreen);
94 splitscreen_handle_deactivate(struct wl_client *client,
95 struct wl_resource *splitscreen_resource)
97 struct ds_tizen_splitscreen *splitscreen;
99 splitscreen = wl_resource_get_user_data(splitscreen_resource);
101 ds_inf("screen_splitscreen:%p deactivate", splitscreen);
103 wl_signal_emit(&splitscreen->events.deactivate, splitscreen);
106 static const struct wtz_splitscreen_interface splitscreen_impl =
108 .destroy = splitscreen_handle_destroy,
109 .activate = splitscreen_handle_activate,
110 .deactivate = splitscreen_handle_deactivate,
114 _tizen_screen_splitscreen_handle_resource_destroy(struct wl_resource *splitscreen_resource)
116 struct ds_tizen_splitscreen *splitscreen;
117 struct ds_tizen_screen *screen;
119 splitscreen = wl_resource_get_user_data(splitscreen_resource);
121 ds_inf("screen_splitscreen:%p destroy", splitscreen);
123 wl_signal_emit(&splitscreen->events.destroy, splitscreen);
125 screen = splitscreen->screen;
126 screen->splitscreen_enabled = false; // unset splitscreen resource on a screen
132 screen_handle_get_splitscreen(struct wl_client *client,
133 struct wl_resource *screen_client_resource,
136 struct ds_tizen_screen_client *screen_client;
137 struct ds_tizen_splitscreen *splitscreen;
138 struct ds_tizen_screen *screen;
140 screen_client = wl_resource_get_user_data(screen_client_resource);
142 screen = screen_client->screen;
144 if (!screen->splitscreen_capability) {
145 wl_resource_post_error(screen_client_resource, WTZ_SCREEN_ERROR_NOT_SUPPORTED,
150 // check splitscreen resource on a screen
151 // splitscreen resource is only one per a screen.
152 if (screen->splitscreen_enabled) {
153 wl_resource_post_error(screen_client_resource, WTZ_SCREEN_ERROR_INVALID_PARAMETER,
158 splitscreen = calloc(1, sizeof *splitscreen);
160 wl_client_post_no_memory(client);
164 splitscreen->resource = wl_resource_create(client, &wtz_splitscreen_interface,
165 wl_resource_get_version(screen_client_resource), id);
166 if (!splitscreen->resource) {
167 wl_client_post_no_memory(client);
172 splitscreen->screen_client = screen_client;
173 splitscreen->screen = screen;
175 wl_resource_set_implementation(splitscreen->resource, &splitscreen_impl,
176 splitscreen, _tizen_screen_splitscreen_handle_resource_destroy);
178 ds_inf("screen_splitscreen:%p create", splitscreen);
180 wl_signal_init(&splitscreen->events.destroy);
181 wl_signal_init(&splitscreen->events.activate);
182 wl_signal_init(&splitscreen->events.deactivate);
184 screen->splitscreen_enabled = true; // set splitscreen resource on a screen
186 wl_signal_emit(&screen_client->screen->events.get_splitscreen, splitscreen);
190 screen_handle_destroy(struct wl_client *wl_client,
191 struct wl_resource *resource)
193 wl_resource_destroy(resource);
196 static const struct wtz_screen_interface screen_impl =
198 .destroy = screen_handle_destroy,
199 .get_splitscreen = screen_handle_get_splitscreen,
203 _tizen_screen_client_handle_resource_destroy(struct wl_resource *resource)
205 struct ds_tizen_screen_client *client;
207 client = wl_resource_get_user_data(resource);
209 ds_inf("_tizen_screen_client_handle_destroy (client:%p)", client);
211 wl_list_remove(&client->link);
216 screen_bind(struct wl_client *wl_client, void *data, uint32_t version,
219 struct ds_tizen_screen *screen = data;
220 struct ds_tizen_screen_client *screen_client;
222 screen_client = calloc(1, sizeof *screen_client);
223 if (screen_client == NULL) {
224 ds_err("calloc() failed. tizen_screen");
225 wl_client_post_no_memory(wl_client);
229 ds_inf("tizen_screen_client binds. (screen_client:%p)", screen_client);
231 screen_client->screen = screen;
232 screen_client->client = wl_client;
234 screen_client->resource = wl_resource_create(wl_client, &wtz_screen_interface,
235 MIN(version, TIZEN_SCREEN_VERSION), id);
236 if (screen_client->resource == NULL) {
237 ds_err("tizen_screen : wl_resource_create() failed.");
239 wl_client_post_no_memory(wl_client);
243 wl_resource_set_implementation(screen_client->resource, &screen_impl, screen_client,
244 _tizen_screen_client_handle_resource_destroy);
246 // send the capabilities of the screen
247 wtz_screen_send_capabilities(screen_client->resource, &screen->capabilities);
249 wl_signal_init(&screen_client->events.destroy);
251 wl_list_insert(&screen->clients, &screen_client->link);
255 screen_handle_display_destroy(struct wl_listener *listener, void *data)
257 struct ds_tizen_screen *screen;
259 screen = wl_container_of(listener, screen, destroy);
261 ds_inf("Global destroy: screen(%p)", screen);
263 wl_signal_emit(&screen->events.destroy, screen);
264 wl_list_remove(&screen->destroy.link);
265 wl_global_destroy(screen->global);
269 WL_EXPORT struct ds_tizen_screen *
270 ds_tizen_screen_create(struct wl_display *display)
272 struct ds_tizen_screen *screen;
274 screen = calloc(1, sizeof *screen);
276 ds_err("calloc() failed.");
280 screen->global = wl_global_create(display, &wtz_screen_interface,
281 TIZEN_SCREEN_VERSION, screen, screen_bind);
282 if (!screen->global) {
283 ds_err("wl_global_create() failed. wtz_screen_interface");
288 wl_list_init(&screen->clients);
290 screen->destroy.notify = screen_handle_display_destroy;
291 wl_display_add_destroy_listener(display, &screen->destroy);
293 wl_array_init(&screen->capabilities);
295 wl_signal_init(&screen->events.destroy);
296 wl_signal_init(&screen->events.get_splitscreen);
298 ds_inf("Global created: tizen_screen(%p)", screen);
304 _screen_capability_add(struct wl_array *capabilities, uint32_t cap)
308 c = wl_array_add(capabilities, sizeof(*c));
312 ds_err("wl_array_add() failed");
316 ds_tizen_screen_add_capability(
317 struct ds_tizen_screen *screen,
318 enum ds_tizen_screen_capability cap)
322 ds_inf("screen:%p add capability(%d)", screen, cap);
324 if (cap == DS_TIZEN_SCREEN_CAPABILITY_SPLITSCREEN) {
325 capability = WTZ_SCREEN_CAPABILITY_SPLITSCREEN;
326 screen->splitscreen_capability = 1;
328 capability = WTZ_SCREEN_CAPABILITY_NONE;
330 _screen_capability_add(&screen->capabilities, capability);
334 ds_tizen_screen_add_destroy_listener(
335 struct ds_tizen_screen *screen,
336 struct wl_listener *listener)
338 wl_signal_add(&screen->events.destroy, listener);
342 ds_tizen_screen_add_get_splitscreen_listener(
343 struct ds_tizen_screen *screen,
344 struct wl_listener *listener)
346 wl_signal_add(&screen->events.get_splitscreen, listener);
350 ds_tizen_splitscreen_add_destroy_listener(
351 struct ds_tizen_splitscreen *splitscreen,
352 struct wl_listener *listener)
354 wl_signal_add(&splitscreen->events.destroy, listener);
358 ds_tizen_splitscreen_add_activate_listener(
359 struct ds_tizen_splitscreen *splitscreen,
360 struct wl_listener *listener)
362 wl_signal_add(&splitscreen->events.activate, listener);
366 ds_tizen_splitscreen_add_deactivate_listener(
367 struct ds_tizen_splitscreen *splitscreen,
368 struct wl_listener *listener)
370 wl_signal_add(&splitscreen->events.deactivate, listener);
374 splitscreen_region_handle_destroy(struct wl_client *client,
375 struct wl_resource *splitscreen_region_resource)
377 wl_resource_destroy(splitscreen_region_resource);
381 splitscreen_region_handle_assign_appid(struct wl_client *client,
382 struct wl_resource *splitscreen_region_resource, const char *appid)
384 struct ds_tizen_splitscreen_region *splitscreen_region;
386 splitscreen_region = wl_resource_get_user_data(splitscreen_region_resource);
388 ds_inf("screen_splitscreen_region:%p assign_appid", splitscreen_region);
390 splitscreen_region->appid = appid;
392 wl_signal_emit(&splitscreen_region->events.assign_appid, (void *)appid);
395 static const struct wtz_splitscreen_region_interface splitscreen_region_impl =
397 .destroy = splitscreen_region_handle_destroy,
398 .assign_appid = splitscreen_region_handle_assign_appid,
402 _tizen_screen_splitscreen_region_handle_resource_destroy(
403 struct wl_resource *splitscreen_region_resource)
405 struct ds_tizen_splitscreen_region *splitscreen_region;
407 splitscreen_region = wl_resource_get_user_data(splitscreen_region_resource);
409 ds_inf("screen_splitscreen_region:%p destroy", splitscreen_region);
411 wl_signal_emit(&splitscreen_region->events.destroy,
414 free(splitscreen_region);
417 WL_EXPORT struct ds_tizen_splitscreen_region *
418 ds_tizen_splitscreen_region_create(
419 struct ds_tizen_splitscreen *splitscreen,
420 const char *name, int32_t x, int32_t y, uint32_t w, uint32_t h)
422 struct ds_tizen_splitscreen_region *splitscreen_region;
423 struct ds_tizen_screen_client *screen_client;
425 splitscreen_region = calloc(1, sizeof *splitscreen_region);
426 if (!splitscreen_region) {
427 ds_err("calloc() failed.");
431 screen_client = splitscreen->screen_client;
433 splitscreen_region->resource = wl_resource_create(screen_client->client,
434 &wtz_splitscreen_region_interface,
435 TIZEN_SCREEN_VERSION, 0);
436 if (!splitscreen_region->resource) {
437 ds_err("wl_resource_create() failed. wtz_splitscreen_region_interface");
438 free(splitscreen_region);
442 wl_resource_set_implementation(splitscreen_region->resource,
443 &splitscreen_region_impl, splitscreen_region,
444 _tizen_screen_splitscreen_region_handle_resource_destroy);
446 // send the splitscreen_region resources
447 wtz_splitscreen_send_region(splitscreen->resource, splitscreen_region->resource);
449 // send the name of the split_screen_region
450 wtz_splitscreen_region_send_name(splitscreen_region->resource, name);
452 // send the geometry of the split_screen_region
453 wtz_splitscreen_region_send_geometry(
454 splitscreen_region->resource, x, y, w, h);
456 return splitscreen_region;
460 ds_tizen_splitscreen_region_add_destroy_listener(
461 struct ds_tizen_splitscreen_region *splitscreen_region,
462 struct wl_listener *listener)
464 wl_signal_add(&splitscreen_region->events.destroy, listener);
468 ds_tizen_splitscreen_region_add_assign_appid_listener(
469 struct ds_tizen_splitscreen_region *splitscreen_region,
470 struct wl_listener *listener)
472 wl_signal_add(&splitscreen_region->events.assign_appid, listener);