4 #include <wayland-server.h>
5 #include <tizen-extension-server-protocol.h>
9 #include "libds-tizen/indicator.h"
11 #define TIZEN_INDICATOR_VERSION 1
13 struct ds_tizen_indicator
15 struct wl_global *global;
17 struct wl_list clients;
19 struct wl_listener destroy;
22 struct wl_signal destroy;
23 struct wl_signal change_state;
24 struct wl_signal change_opacity_mode;
25 struct wl_signal change_visible_type;
29 struct ds_tizen_indicator_client
31 struct ds_tizen_indicator *indicator;
33 struct wl_resource *resource;
34 struct wl_client *wl_client;
38 struct wl_list link; // ds_tizen_indicator::clients
41 struct ds_tizen_indicator_info
43 struct ds_surface *surface;
45 enum ds_tizen_indicator_state state;
46 enum ds_tizen_indicator_opacity_mode opacity_mode;
47 enum ds_tizen_indicator_visible_type visible_type;
49 struct wl_list link; // ds_tizen_indicator_client::infos
52 static void indicator_handle_display_destroy(struct wl_listener *listener,
55 static void indicator_bind(struct wl_client *wl_client, void *data,
56 uint32_t version, uint32_t id);
58 static struct ds_tizen_indicator_client *tizen_indicator_find_client(
59 struct ds_tizen_indicator *indicator,
60 struct ds_surface *surface);
62 static struct ds_tizen_indicator_info *tizen_indicator_find_info(
63 struct ds_tizen_indicator *indicator,
64 struct ds_surface *surface);
66 static struct ds_tizen_indicator_info *tizen_indicator_client_find_info(
67 struct ds_tizen_indicator_client *client,
68 struct ds_surface *surface);
70 static struct ds_tizen_indicator_info *tizen_indicator_client_get_info(
71 struct ds_tizen_indicator_client *client,
72 struct ds_surface *surface);
74 WL_EXPORT struct ds_tizen_indicator *
75 ds_tizen_indicator_create(struct wl_display *display)
77 struct ds_tizen_indicator *indicator;
79 indicator = calloc(1, sizeof *indicator);
81 ds_err("calloc() failed.");
85 indicator->global = wl_global_create(display, &tizen_indicator_interface,
86 TIZEN_INDICATOR_VERSION, indicator, indicator_bind);
87 if (!indicator->global) {
88 ds_err("wl_global_create() failed. tizen_indicator_interface");
93 wl_list_init(&indicator->clients);
95 indicator->destroy.notify = indicator_handle_display_destroy;
96 wl_display_add_destroy_listener(display, &indicator->destroy);
98 wl_signal_init(&indicator->events.destroy);
99 wl_signal_init(&indicator->events.change_state);
100 wl_signal_init(&indicator->events.change_opacity_mode);
101 wl_signal_init(&indicator->events.change_visible_type);
103 ds_inf("Global created: tizen_indicator(%p)", indicator);
109 ds_tizen_indicator_add_destroy_listener(struct ds_tizen_indicator *indicator,
110 struct wl_listener *listener)
112 wl_signal_add(&indicator->events.destroy, listener);
116 ds_tizen_indicator_add_change_state_listener(
117 struct ds_tizen_indicator *indicator, struct wl_listener *listener)
119 wl_signal_add(&indicator->events.change_state, listener);
123 ds_tizen_indicator_add_change_opacity_mode_listener(
124 struct ds_tizen_indicator *indicator, struct wl_listener *listener)
126 wl_signal_add(&indicator->events.change_opacity_mode, listener);
130 ds_tizen_indicator_add_change_visible_type_listener(
131 struct ds_tizen_indicator *indicator, struct wl_listener *listener)
133 wl_signal_add(&indicator->events.change_visible_type, listener);
136 WL_EXPORT enum ds_tizen_indicator_state
137 ds_tizen_indicator_get_state(struct ds_tizen_indicator *indicator,
138 struct ds_surface *surface)
140 struct ds_tizen_indicator_info *info;
142 info = tizen_indicator_find_info(indicator, surface);
144 ds_err("tizen_indicator: tizen_indicator_find_info() failed.");
145 return DS_TIZEN_INDICATOR_STATE_UNKNOWN;
151 WL_EXPORT enum ds_tizen_indicator_opacity_mode
152 ds_tizen_indicator_get_opacity_mode(struct ds_tizen_indicator *indicator,
153 struct ds_surface *surface)
155 struct ds_tizen_indicator_info *info;
157 info = tizen_indicator_find_info(indicator, surface);
159 ds_err("tizen_indicator: tizen_indicator_find_info() failed.");
160 return DS_TIZEN_INDICATOR_OPACITY_MODE_UNKNOWN;
163 return info->opacity_mode;
166 WL_EXPORT enum ds_tizen_indicator_visible_type
167 ds_tizen_indicator_get_visible_type(struct ds_tizen_indicator *indicator,
168 struct ds_surface *surface)
170 struct ds_tizen_indicator_info *info;
172 info = tizen_indicator_find_info(indicator, surface);
174 ds_err("tizen_indicator: tizen_indicator_find_info() failed.");
175 return DS_TIZEN_INDICATOR_VISIBLE_TYPE_HIDDEN;
178 return info->visible_type;
182 ds_tizen_indicator_send_flick(struct ds_tizen_indicator *indicator,
183 struct ds_surface *surface)
185 struct ds_tizen_indicator_client *client;
187 client = tizen_indicator_find_client(indicator, surface);
188 if (client == NULL) {
189 ds_err("tizen_indicator: tizen_indicator_find_client() failed.");
193 tizen_indicator_send_flick(client->resource,
194 ds_surface_get_wl_resource(surface), 0);
197 static struct ds_tizen_indicator_client *
198 tizen_indicator_find_client(struct ds_tizen_indicator *indicator,
199 struct ds_surface *surface)
201 struct ds_tizen_indicator_info *info;
202 struct ds_tizen_indicator_client *client;
204 wl_list_for_each(client, &indicator->clients, link) {
205 info = tizen_indicator_client_find_info(client, surface);
213 static struct ds_tizen_indicator_info *
214 tizen_indicator_find_info(struct ds_tizen_indicator *indicator,
215 struct ds_surface *surface)
217 struct ds_tizen_indicator_info *info;
218 struct ds_tizen_indicator_client *client;
220 wl_list_for_each(client, &indicator->clients, link) {
221 info = tizen_indicator_client_find_info(client, surface);
229 static struct ds_tizen_indicator_info *
230 tizen_indicator_client_find_info(struct ds_tizen_indicator_client *client,
231 struct ds_surface *surface)
233 struct ds_tizen_indicator_info *info;
235 wl_list_for_each(info, &client->infos, link) {
236 if (surface == info->surface)
243 static struct ds_tizen_indicator_info *
244 tizen_indicator_client_get_info(struct ds_tizen_indicator_client *client,
245 struct ds_surface *surface)
247 struct ds_tizen_indicator_info *info;
249 info = tizen_indicator_client_find_info(client, surface);
253 info = calloc(1, sizeof *info);
255 ds_err("calloc() failed. tizen_indicator");
259 info->surface = surface;
261 // The initial values of state, opacity_mode and visible_type are not
262 // each value of enum ds_tizen_indicator_state,
263 // enum ds_tizen_indicator_opacity_mode and
264 // enum ds_tizen_indicator_opacity_mode
265 // because of the first signal emit for change_state signal.
266 info->state = DS_TIZEN_INDICATOR_STATE_UNKNOWN;
267 info->opacity_mode = DS_TIZEN_INDICATOR_OPACITY_MODE_UNKNOWN;
268 info->visible_type = DS_TIZEN_INDICATOR_VISIBLE_TYPE_HIDDEN;
270 wl_list_insert(&client->infos, &info->link);
276 indicator_handle_display_destroy(struct wl_listener *listener, void *data)
278 struct ds_tizen_indicator *indicator;
280 indicator = wl_container_of(listener, indicator, destroy);
282 ds_inf("Global destroy: indicator(%p)", indicator);
284 wl_signal_emit_mutable(&indicator->events.destroy, indicator);
285 wl_list_remove(&indicator->destroy.link);
286 wl_global_destroy(indicator->global);
291 indicator_handle_destroy(struct wl_client *wl_client,
292 struct wl_resource *resource)
294 struct ds_tizen_indicator_client *client;
296 client = wl_resource_get_user_data(resource);
298 if (!wl_list_empty(&client->infos)) {
299 ds_err("tizen_indicator was destroyed before children");
303 wl_resource_destroy(resource);
307 indicator_handle_set_state(struct wl_client *wl_client,
308 struct wl_resource *resource, struct wl_resource *surface_resource,
311 struct ds_tizen_indicator_client *client;
312 struct ds_tizen_indicator_info *info;
313 struct ds_surface *surface;
314 enum ds_tizen_indicator_state indicator_state;
316 ds_inf("tizen_indicator: set_state : state %d", state);
318 client = wl_resource_get_user_data(resource);
319 surface = ds_surface_from_resource(surface_resource);
321 info = tizen_indicator_client_get_info(client, surface);
323 ds_err("tizen_indicator_client_get_info() failed. tizen_indicator");
324 wl_client_post_no_memory(wl_client);
329 case TIZEN_INDICATOR_STATE_OFF:
330 indicator_state = DS_TIZEN_INDICATOR_STATE_OFF;
332 case TIZEN_INDICATOR_STATE_ON:
333 indicator_state = DS_TIZEN_INDICATOR_STATE_ON;
336 indicator_state = DS_TIZEN_INDICATOR_STATE_UNKNOWN;
340 if (info->state != indicator_state) {
341 ds_inf("tizen_indicator: surface : %p, change_state : %d -> %d",
342 surface, info->state, indicator_state);
343 info->state = indicator_state;
345 wl_signal_emit_mutable(&client->indicator->events.change_state, surface);
350 indicator_handle_set_opacity_mode(struct wl_client *wl_client,
351 struct wl_resource *resource, struct wl_resource *surface_resource,
354 struct ds_tizen_indicator_client *client;
355 struct ds_tizen_indicator_info *info;
356 struct ds_surface *surface;
357 enum ds_tizen_indicator_opacity_mode opacity_mode;
359 ds_inf("tizen_indicator: set_opacity_mode : opacity_mode %d", mode);
361 client = wl_resource_get_user_data(resource);
362 surface = ds_surface_from_resource(surface_resource);
364 info = tizen_indicator_client_get_info(client, surface);
366 ds_err("tizen_indicator_client_get_info() failed. tizen_indicator");
367 wl_client_post_no_memory(wl_client);
372 case TIZEN_INDICATOR_OPACITY_MODE_OPAQUE:
373 opacity_mode = DS_TIZEN_INDICATOR_OPACITY_MODE_OPAQUE;
375 case TIZEN_INDICATOR_OPACITY_MODE_TRANSLUCENT:
376 opacity_mode = DS_TIZEN_INDICATOR_OPACITY_MODE_TRANSLUCENT;
378 case TIZEN_INDICATOR_OPACITY_MODE_TRANSPARENT:
379 opacity_mode = DS_TIZEN_INDICATOR_OPACITY_MODE_TRANSPARENT;
381 case TIZEN_INDICATOR_OPACITY_MODE_BG_TRANSPARENT:
382 opacity_mode = DS_TIZEN_INDICATOR_OPACITY_MODE_BG_TRANSPARENT;
385 opacity_mode = DS_TIZEN_INDICATOR_OPACITY_MODE_UNKNOWN;
389 if (info->opacity_mode != opacity_mode) {
390 ds_inf("tizen_indicator: surface : %p, change_opacity_mode : %d -> %d",
391 surface, info->opacity_mode, opacity_mode);
392 info->opacity_mode = opacity_mode;
394 wl_signal_emit_mutable(&client->indicator->events.change_opacity_mode, surface);
399 indicator_handle_set_visible_type(struct wl_client *wl_client,
400 struct wl_resource *resource, struct wl_resource *surface_resource,
403 struct ds_tizen_indicator_client *client;
404 struct ds_tizen_indicator_info *info;
405 struct ds_surface *surface;
406 enum ds_tizen_indicator_visible_type visible_type;
408 ds_inf("tizen_indicator: set_visible_type : visible_type %d", type);
410 client = wl_resource_get_user_data(resource);
411 surface = ds_surface_from_resource(surface_resource);
413 info = tizen_indicator_client_get_info(client, surface);
415 ds_err("tizen_indicator_client_get_info() failed. tizen_indicator");
416 wl_client_post_no_memory(wl_client);
421 case TIZEN_INDICATOR_VISIBLE_TYPE_SHOWN:
422 visible_type = DS_TIZEN_INDICATOR_VISIBLE_TYPE_SHOWN;
425 visible_type = DS_TIZEN_INDICATOR_VISIBLE_TYPE_HIDDEN;
429 if (info->visible_type != visible_type) {
430 ds_inf("tizen_indicator: surface : %p, change_visible_type : %d -> %d",
431 surface, info->visible_type, visible_type);
432 info->visible_type = visible_type;
434 wl_signal_emit_mutable(&client->indicator->events.change_visible_type, surface);
438 static const struct tizen_indicator_interface indicator_impl =
440 indicator_handle_destroy,
441 indicator_handle_set_state,
442 indicator_handle_set_opacity_mode,
443 indicator_handle_set_visible_type,
447 _tizen_indicator_client_handle_destroy(struct wl_resource *resource)
449 struct ds_tizen_indicator_client *client;
450 struct ds_tizen_indicator_info *info, *tmp;
452 client = wl_resource_get_user_data(resource);
454 ds_inf("_tizen_indicator_client_handle_destroy (client:%p)", client);
456 wl_list_for_each_safe(info, tmp, &client->infos, link) {
457 wl_list_remove(&info->link);
461 wl_list_remove(&client->link);
466 indicator_bind(struct wl_client *wl_client, void *data, uint32_t version,
469 struct ds_tizen_indicator *indicator = data;
470 struct ds_tizen_indicator_client *client;
472 client = calloc(1, sizeof *client);
473 if (client == NULL) {
474 ds_err("calloc() failed. tizen_indicator");
475 wl_client_post_no_memory(wl_client);
479 ds_inf("tizen_indicator_client binds. (client:%p)", client);
481 client->indicator = indicator;
482 client->wl_client = wl_client;
484 wl_list_init(&client->infos);
486 client->resource = wl_resource_create(wl_client, &tizen_indicator_interface,
487 MIN(version, TIZEN_INDICATOR_VERSION), id);
488 if (client->resource == NULL) {
489 ds_err("tizen_indicator : wl_resource_create() failed.");
491 wl_client_post_no_memory(wl_client);
495 wl_resource_set_implementation(client->resource, &indicator_impl, client,
496 _tizen_indicator_client_handle_destroy);
498 wl_list_insert(&indicator->clients, &client->link);