4 #include <wayland-server.h>
5 #include <tizen-extension-server-protocol.h>
9 #include "libds-tizen/clipboard.h"
11 #define TIZEN_CLIPBOARD_VERSION 2
13 struct ds_tizen_clipboard
15 struct wl_global *global;
17 struct wl_list clients;
19 struct wl_listener destroy;
22 struct wl_signal destroy;
23 struct wl_signal show;
24 struct wl_signal hide;
25 struct wl_signal set_data_only;
29 struct ds_tizen_clipboard_client
31 struct ds_tizen_clipboard *clipboard;
33 struct wl_resource *resource;
34 struct wl_client *wl_client;
40 struct wl_list link; // ds_tizen_clipboard::clients
43 struct ds_tizen_clipboard_info
45 struct ds_surface *surface;
47 struct wl_list link; // ds_tizen_clipboard_client::infos
50 static void clipboard_handle_display_destroy(struct wl_listener *listener,
53 static void clipboard_bind(struct wl_client *wl_client, void *data,
54 uint32_t version, uint32_t id);
56 static struct ds_tizen_clipboard_client *tizen_clipboard_find_client(
57 struct ds_tizen_clipboard *clipboard,
58 struct ds_surface *surface);
60 static struct ds_tizen_clipboard_info *tizen_clipboard_client_find_info(
61 struct ds_tizen_clipboard_client *client,
62 struct ds_surface *surface);
64 static struct ds_tizen_clipboard_info *tizen_clipboard_client_get_info(
65 struct ds_tizen_clipboard_client *client,
66 struct ds_surface *surface);
68 WL_EXPORT struct ds_tizen_clipboard *
69 ds_tizen_clipboard_create(struct wl_display *display)
71 struct ds_tizen_clipboard *clipboard;
73 clipboard = calloc(1, sizeof *clipboard);
75 ds_err("calloc() failed.");
79 clipboard->global = wl_global_create(display, &tizen_clipboard_interface,
80 TIZEN_CLIPBOARD_VERSION, clipboard, clipboard_bind);
81 if (!clipboard->global) {
82 ds_err("wl_global_create() failed. tizen_clipboard_interface");
87 wl_list_init(&clipboard->clients);
89 clipboard->destroy.notify = clipboard_handle_display_destroy;
90 wl_display_add_destroy_listener(display, &clipboard->destroy);
92 wl_signal_init(&clipboard->events.destroy);
93 wl_signal_init(&clipboard->events.show);
94 wl_signal_init(&clipboard->events.hide);
95 wl_signal_init(&clipboard->events.set_data_only);
97 ds_inf("Global created: tizen_clipboard(%p)", clipboard);
103 ds_tizen_clipboard_add_destroy_listener(struct ds_tizen_clipboard *clipboard,
104 struct wl_listener *listener)
106 wl_signal_add(&clipboard->events.destroy, listener);
110 ds_tizen_clipboard_add_show_listener(
111 struct ds_tizen_clipboard *clipboard, struct wl_listener *listener)
113 wl_signal_add(&clipboard->events.show, listener);
117 ds_tizen_clipboard_add_hide_listener(
118 struct ds_tizen_clipboard *clipboard, struct wl_listener *listener)
120 wl_signal_add(&clipboard->events.hide, listener);
124 ds_tizen_clipboard_add_set_data_only_listener(
125 struct ds_tizen_clipboard *clipboard, struct wl_listener *listener)
127 wl_signal_add(&clipboard->events.set_data_only, listener);
131 ds_tizen_clipboard_client_get_data_only(
132 struct ds_tizen_clipboard_client *client)
134 return client->data_only;
138 ds_tizen_clipboard_send_data_selected(struct ds_tizen_clipboard *clipboard,
139 struct ds_surface *surface)
141 struct ds_tizen_clipboard_client *client;
143 client = tizen_clipboard_find_client(clipboard, surface);
144 if (client == NULL) {
145 ds_err("tizen_clipboard: tizen_clipboard_find_client() failed.");
149 tizen_clipboard_send_data_selected(client->resource,
150 ds_surface_get_wl_resource(surface));
154 ds_tizen_clipboard_client_send_allowed_data_only(
155 struct ds_tizen_clipboard_client *client, uint32_t allowed)
157 tizen_clipboard_send_allowed_data_only(client->resource, allowed);
160 static struct ds_tizen_clipboard_client *
161 tizen_clipboard_find_client(struct ds_tizen_clipboard *clipboard,
162 struct ds_surface *surface)
164 struct ds_tizen_clipboard_info *info;
165 struct ds_tizen_clipboard_client *client;
167 wl_list_for_each(client, &clipboard->clients, link) {
168 info = tizen_clipboard_client_find_info(client, surface);
176 static struct ds_tizen_clipboard_info *
177 tizen_clipboard_client_find_info(struct ds_tizen_clipboard_client *client,
178 struct ds_surface *surface)
180 struct ds_tizen_clipboard_info *info;
182 wl_list_for_each(info, &client->infos, link) {
183 if (surface == info->surface)
190 static struct ds_tizen_clipboard_info *
191 tizen_clipboard_client_get_info(struct ds_tizen_clipboard_client *client,
192 struct ds_surface *surface)
194 struct ds_tizen_clipboard_info *info;
196 info = tizen_clipboard_client_find_info(client, surface);
200 info = calloc(1, sizeof *info);
202 ds_err("calloc() failed. tizen_clipboard");
206 info->surface = surface;
208 wl_list_insert(&client->infos, &info->link);
214 clipboard_handle_display_destroy(struct wl_listener *listener, void *data)
216 struct ds_tizen_clipboard *clipboard;
218 clipboard = wl_container_of(listener, clipboard, destroy);
220 ds_inf("Global destroy: clipboard(%p)", clipboard);
222 wl_signal_emit_mutable(&clipboard->events.destroy, clipboard);
223 wl_list_remove(&clipboard->destroy.link);
224 wl_global_destroy(clipboard->global);
229 clipboard_handle_destroy(struct wl_client *wl_client,
230 struct wl_resource *resource)
232 struct ds_tizen_clipboard_client *client;
234 client = wl_resource_get_user_data(resource);
236 if (!wl_list_empty(&client->infos)) {
237 ds_err("tizen_clipboard was destroyed before children");
241 wl_resource_destroy(resource);
245 clipboard_handle_show(struct wl_client *wl_client,
246 struct wl_resource *resource, struct wl_resource *surface_resource)
248 struct ds_tizen_clipboard_client *client;
249 struct ds_tizen_clipboard_info *info;
250 struct ds_surface *surface;
252 ds_inf("tizen_clipboard: show");
254 client = wl_resource_get_user_data(resource);
255 surface = ds_surface_from_resource(surface_resource);
257 info = tizen_clipboard_client_get_info(client, surface);
259 ds_err("tizen_clipboard_client_get_info() failed. tizen_clipboard");
260 wl_client_post_no_memory(wl_client);
264 wl_signal_emit_mutable(&client->clipboard->events.show, surface);
268 clipboard_handle_hide(struct wl_client *wl_client,
269 struct wl_resource *resource, struct wl_resource *surface_resource)
271 struct ds_tizen_clipboard_client *client;
272 struct ds_tizen_clipboard_info *info;
273 struct ds_surface *surface;
275 ds_inf("tizen_clipboard: hide");
277 client = wl_resource_get_user_data(resource);
278 surface = ds_surface_from_resource(surface_resource);
280 info = tizen_clipboard_client_get_info(client, surface);
282 ds_err("tizen_clipboard_client_get_info() failed. tizen_clipboard");
283 wl_client_post_no_memory(wl_client);
287 wl_signal_emit_mutable(&client->clipboard->events.hide, surface);
291 clipboard_handle_set_data_only(struct wl_client *wl_client,
292 struct wl_resource *resource, uint32_t set)
294 struct ds_tizen_clipboard_client *client;
296 ds_inf("tizen_clipboard: set_data_only. set(%d)", set);
298 client = wl_resource_get_user_data(resource);
299 client->data_only = set;
301 wl_signal_emit_mutable(&client->clipboard->events.set_data_only, client);
304 static const struct tizen_clipboard_interface clipboard_impl =
306 clipboard_handle_destroy,
307 clipboard_handle_show,
308 clipboard_handle_hide,
309 clipboard_handle_set_data_only,
313 _tizen_clipboard_client_handle_destroy(struct wl_resource *resource)
315 struct ds_tizen_clipboard_client *client;
316 struct ds_tizen_clipboard_info *info, *tmp;
318 client = wl_resource_get_user_data(resource);
320 ds_inf("_tizen_clipboard_client_handle_destroy (client:%p)", client);
322 wl_list_for_each_safe(info, tmp, &client->infos, link) {
323 wl_list_remove(&info->link);
327 wl_list_remove(&client->link);
332 clipboard_bind(struct wl_client *wl_client, void *data, uint32_t version,
335 struct ds_tizen_clipboard *clipboard = data;
336 struct ds_tizen_clipboard_client *client;
338 client = calloc(1, sizeof *client);
339 if (client == NULL) {
340 ds_err("calloc() failed. tizen_clipboard");
341 wl_client_post_no_memory(wl_client);
345 ds_inf("tizen_clipboard_client binds. (client:%p)", client);
347 client->clipboard = clipboard;
348 client->wl_client = wl_client;
350 wl_list_init(&client->infos);
352 client->resource = wl_resource_create(wl_client, &tizen_clipboard_interface,
353 MIN(version, TIZEN_CLIPBOARD_VERSION), id);
355 if (client->resource == NULL) {
356 ds_err("tizen_clipboard : wl_resource_create() failed.");
358 wl_client_post_no_memory(wl_client);
362 wl_resource_set_implementation(client->resource, &clipboard_impl, client,
363 _tizen_clipboard_client_handle_destroy);
365 wl_list_insert(&clipboard->clients, &client->link);