4 #include <wayland-server.h>
5 #include <tizen-extension-server-protocol.h>
9 #include "libds-tizen/screen_rotation.h"
11 #define TIZEN_SCREEN_ROTATION_VERSION 1
13 struct ds_tizen_screen_rotation
15 struct wl_global *global;
17 struct wl_list clients;
19 struct wl_listener destroy;
22 struct wl_signal destroy;
23 struct wl_signal get_ignore_output_transfrom;
27 struct ds_tizen_screen_rotation_client
29 struct ds_tizen_screen_rotation *screen_rotation;
31 struct wl_resource *resource;
32 struct wl_client *wl_client;
37 struct wl_signal destroy;
40 struct wl_list link; // ds_tizen_screen_rotation::clients
43 struct ds_tizen_screen_rotation_info
45 struct ds_tizen_screen_rotation_client *client;
47 struct ds_surface *surface;
49 struct wl_list link; // ds_tizen_screen_rotation_client::infos
52 static void screen_rotation_handle_display_destroy(struct wl_listener *listener,
55 static void screen_rotation_bind(struct wl_client *wl_client, void *data,
56 uint32_t version, uint32_t id);
58 static struct ds_tizen_screen_rotation_info *tizen_screen_rotation_client_find_info(
59 struct ds_tizen_screen_rotation_client *client,
60 struct ds_surface *surface);
62 static struct ds_tizen_screen_rotation_info *tizen_screen_rotation_client_get_info(
63 struct ds_tizen_screen_rotation_client *client,
64 struct ds_surface *surface);
66 WL_EXPORT struct ds_tizen_screen_rotation *
67 ds_tizen_screen_rotation_create(struct wl_display *display)
69 struct ds_tizen_screen_rotation *screen_rotation;
71 screen_rotation = calloc(1, sizeof *screen_rotation);
72 if (!screen_rotation) {
73 ds_err("calloc() failed.");
77 screen_rotation->global = wl_global_create(display,
78 &tizen_screen_rotation_interface, TIZEN_SCREEN_ROTATION_VERSION,
79 screen_rotation, screen_rotation_bind);
80 if (!screen_rotation->global) {
81 ds_err("wl_global_create() failed. tizen_screen_rotation_interface");
82 free(screen_rotation);
86 wl_list_init(&screen_rotation->clients);
88 screen_rotation->destroy.notify = screen_rotation_handle_display_destroy;
89 wl_display_add_destroy_listener(display, &screen_rotation->destroy);
91 wl_signal_init(&screen_rotation->events.destroy);
92 wl_signal_init(&screen_rotation->events.get_ignore_output_transfrom);
94 ds_inf("Global created: tizen_screen_rotation(%p)", screen_rotation);
96 return screen_rotation;
100 ds_tizen_screen_rotation_add_destroy_listener(
101 struct ds_tizen_screen_rotation *screen_rotation,
102 struct wl_listener *listener)
104 wl_signal_add(&screen_rotation->events.destroy, listener);
108 ds_tizen_screen_rotation_add_get_ignore_output_transform_info_listener(
109 struct ds_tizen_screen_rotation *screen_rotation,
110 struct wl_listener *listener)
112 wl_signal_add(&screen_rotation->events.get_ignore_output_transfrom,
117 ds_tizen_screen_rotation_info_add_destroy_listener(
118 struct ds_tizen_screen_rotation_info *info,
119 struct wl_listener *listener)
121 wl_signal_add(&info->client->events.destroy, listener);
124 WL_EXPORT struct ds_surface *
125 ds_tizen_screen_rotation_info_get_surface(
126 struct ds_tizen_screen_rotation_info *info)
128 return info->surface;
132 ds_tizen_screen_rotation_send_ignore_output_transform(
133 struct ds_tizen_screen_rotation_info *info, uint32_t ignore)
135 tizen_screen_rotation_send_ignore_output_transform(info->client->resource,
136 ds_surface_get_wl_resource(info->surface), ignore);
139 static struct ds_tizen_screen_rotation_info *
140 tizen_screen_rotation_client_find_info(struct ds_tizen_screen_rotation_client *client,
141 struct ds_surface *surface)
143 struct ds_tizen_screen_rotation_info *info;
145 wl_list_for_each(info, &client->infos, link) {
146 if (surface == info->surface)
153 static struct ds_tizen_screen_rotation_info *
154 tizen_screen_rotation_client_get_info(struct ds_tizen_screen_rotation_client *client,
155 struct ds_surface *surface)
157 struct ds_tizen_screen_rotation_info *info;
159 info = tizen_screen_rotation_client_find_info(client, surface);
163 info = calloc(1, sizeof *info);
165 ds_err("calloc() failed. tizen_screen_rotation");
169 info->client = client;
170 info->surface = surface;
172 wl_list_insert(&client->infos, &info->link);
178 screen_rotation_handle_display_destroy(struct wl_listener *listener, void *data)
180 struct ds_tizen_screen_rotation *screen_rotation;
182 screen_rotation = wl_container_of(listener, screen_rotation, destroy);
184 ds_inf("Global destroy: screen_rotation(%p)", screen_rotation);
186 wl_signal_emit_mutable(&screen_rotation->events.destroy, screen_rotation);
187 wl_list_remove(&screen_rotation->destroy.link);
188 wl_global_destroy(screen_rotation->global);
189 free(screen_rotation);
193 screen_rotation_handle_destroy(struct wl_client *wl_client,
194 struct wl_resource *resource)
196 struct ds_tizen_screen_rotation_client *client;
198 client = wl_resource_get_user_data(resource);
200 if (!wl_list_empty(&client->infos)) {
201 ds_err("tizen_screen_rotation was destroyed before children");
205 wl_resource_destroy(resource);
209 screen_rotation_handle_get_ignore_output_transfrom(struct wl_client *wl_client,
210 struct wl_resource *resource, struct wl_resource *surface_resource)
212 struct ds_tizen_screen_rotation_client *client;
213 struct ds_tizen_screen_rotation_info *info;
214 struct ds_surface *surface;
216 ds_inf("tizen_screen_rotation: get_ignore_output_transfrom");
218 client = wl_resource_get_user_data(resource);
219 surface = ds_surface_from_resource(surface_resource);
221 info = tizen_screen_rotation_client_get_info(client, surface);
223 ds_err("tizen_screen_rotation_client_get_info() failed. tizen_screen_rotation");
224 wl_client_post_no_memory(wl_client);
228 wl_signal_emit_mutable(&client->screen_rotation->events.get_ignore_output_transfrom, info);
231 static const struct tizen_screen_rotation_interface screen_rotation_impl =
233 screen_rotation_handle_get_ignore_output_transfrom,
234 screen_rotation_handle_destroy,
238 _tizen_screen_rotation_client_handle_destroy(struct wl_resource *resource)
240 struct ds_tizen_screen_rotation_client *client;
241 struct ds_tizen_screen_rotation_info *info, *tmp;
243 client = wl_resource_get_user_data(resource);
245 ds_inf("_tizen_screen_rotation_client_handle_destroy (client:%p)", client);
247 wl_list_for_each_safe(info, tmp, &client->infos, link) {
248 wl_signal_emit_mutable(&client->events.destroy, info);
249 wl_list_remove(&info->link);
253 wl_list_remove(&client->link);
258 screen_rotation_bind(struct wl_client *wl_client, void *data, uint32_t version,
261 struct ds_tizen_screen_rotation *screen_rotation = data;
262 struct ds_tizen_screen_rotation_client *client;
264 client = calloc(1, sizeof *client);
265 if (client == NULL) {
266 ds_err("calloc() failed. tizen_screen_rotation");
267 wl_client_post_no_memory(wl_client);
271 ds_inf("tizen_screen_rotation_client binds. (client:%p)", client);
273 client->screen_rotation = screen_rotation;
274 client->wl_client = wl_client;
276 wl_list_init(&client->infos);
278 client->resource = wl_resource_create(wl_client, &tizen_screen_rotation_interface,
279 MIN(version, TIZEN_SCREEN_ROTATION_VERSION), id);
281 if (client->resource == NULL) {
282 ds_err("tizen_screen_rotation : wl_resource_create() failed.");
284 wl_client_post_no_memory(wl_client);
288 wl_resource_set_implementation(client->resource, &screen_rotation_impl, client,
289 _tizen_screen_rotation_client_handle_destroy);
291 wl_signal_init(&client->events.destroy);
293 wl_list_insert(&screen_rotation->clients, &client->link);