hwc: Modify ds_tizen_hwc destruction logic
[platform/core/uifw/libds-tizen.git] / src / remote_surface / remote_surface.c
1 #include <assert.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <wayland-server.h>
5 #include <tizen-remote-surface-server-protocol.h>
6 #include <libds/log.h>
7 #include <stdio.h>
8 #include <fcntl.h>
9
10 #include "util.h"
11 #include "libds-tizen/remote_surface.h"
12 #include <libds-tizen/tbm_server.h>
13
14 #define TIZEN_REMOTE_SURFACE_VERSION 6
15
16 static uint32_t global_resource_id = 1;
17
18 struct ds_tizen_remote_surface_manager
19 {
20     struct wl_global *global;
21
22     struct wl_listener destroy;
23
24     struct wl_list remote_providers;
25     struct wl_list remote_surfaces;
26
27     struct {
28         struct wl_signal destroy;
29         struct wl_signal new_provider;
30         struct wl_signal new_surface;
31         struct wl_signal bind_surface;
32     } events;
33 };
34
35 struct ds_tizen_remote_surface_client
36 {
37     struct ds_tizen_remote_surface_manager *remote_manager;
38
39     struct wl_resource *resource;
40     struct wl_client *wl_client;
41
42     struct {
43         struct wl_listener surface_destroy;
44     } listener;
45
46     struct {
47         struct wl_signal destroy;
48     } events;
49 };
50
51 struct ds_tizen_remote_surface_provider
52 {
53     struct wl_list link;
54
55     struct wl_resource *resource;
56
57     struct ds_surface *surface;
58
59     uint32_t input_event_filter;
60     uint32_t offscreen;
61
62     unsigned int resource_id;
63
64     struct {
65         struct wl_listener surface_destroy;
66     } listener;
67
68     struct {
69         struct wl_signal destroy;
70         struct wl_signal set_offscreen;
71         struct wl_signal set_input_event_filter;
72     } events;
73 };
74
75 struct ds_tizen_remote_surface
76 {
77     struct wl_list link;
78
79     struct wl_resource *resource;
80
81     struct ds_surface *surface;
82
83     struct wl_resource *wl_tbm_resource;
84
85     bool redirect;
86     struct ds_surface *owner_surface;
87     bool remote_render;
88     uint32_t changed_buffer_event_filter;
89
90     struct {
91         struct wl_listener surface_destroy;
92         struct wl_listener owner_surface_destroy;
93         struct wl_listener wl_tbm_resource_destroy;
94     } listener;
95
96     struct {
97         struct wl_signal destroy;
98         struct wl_signal set_redirect;
99         struct wl_signal transfer_mouse_event;
100         struct wl_signal transfer_mouse_wheel_event;
101         struct wl_signal transfer_touch_event;
102         struct wl_signal transfer_touch_cancel_event;
103         struct wl_signal transfer_key_event;
104         struct wl_signal transfer_visibility_event;
105         struct wl_signal set_owner;
106         struct wl_signal new_region;
107         struct wl_signal buffer_release;
108         struct wl_signal set_remote_render;
109         struct wl_signal set_changed_buffer_event_filter;
110         struct wl_signal get_current_buffer;
111     } events;
112 };
113
114 struct ds_tizen_remote_surface_region
115 {
116     struct wl_resource *resource;
117
118     int32_t x;
119     int32_t y;
120     int32_t w;
121     int32_t h;
122
123     struct {
124         struct wl_signal destroy;
125         struct wl_signal set_geometry;
126     } events;
127 };
128
129 static int
130 remote_surface_dummy_fd_get(void)
131 {
132     static const char template[] = "/libds_rsm_dummy_fdXXXXXX";
133     const char *path;
134     char *name;
135     size_t name_size;
136     long flags;
137     static int fd = -1;
138
139     if (fd >= 0)
140         return fd;
141
142     path = getenv("XDG_RUNTIME_DIR");
143     if (!path) {
144         ds_err("fail to get XDG_RUNTIME_DIR");
145         return -1;
146     }
147
148     name_size = strlen(path) + sizeof(template);
149     name = malloc(name_size);
150     if (!name) {
151         ds_err("malloc() failed");
152         return -1;
153     }
154
155     snprintf(name, name_size, "%s%s", path, template);
156     fd = mkstemp(name);
157     if (fd < 0) {
158         ds_err("mkstemp() failed");
159         free(name);
160         return -1;
161     }
162
163     flags = fcntl(fd, F_GETFD);
164     if (flags == -1) {
165         ds_err("fcntl(F_GETFD) failed");
166         unlink(name);
167         free(name);
168         return -1;
169     }
170
171     if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
172         ds_err("fcntl(F_SETFD, FD_CLOEXEC) failed");
173         unlink(name);
174         free(name);
175         return -1;
176     }
177
178     unlink(name);
179     free(name);
180
181     return fd;
182 }
183
184 static void
185 remote_surface_provider_handle_destroy(struct wl_client *wl_client,
186     struct wl_resource *resource)
187 {
188     wl_resource_destroy(resource);
189 }
190
191 static void
192 remote_surface_provider_handle_set_offscreen(struct wl_client *wl_client,
193     struct wl_resource *provider_resource, uint32_t offscreen)
194 {
195     struct ds_tizen_remote_surface_provider *remote_provider;
196
197     remote_provider = wl_resource_get_user_data(provider_resource);
198
199     if (remote_provider->offscreen == offscreen)
200         return;
201
202     remote_provider->offscreen = offscreen;
203
204     wl_signal_emit_mutable(&remote_provider->events.set_offscreen, remote_provider);
205 }
206
207 static void
208 remote_surface_provider_handle_set_input_event_filter(struct wl_client *wl_client,
209     struct wl_resource *provider_resource, uint32_t event_filter)
210 {
211     struct ds_tizen_remote_surface_provider *remote_provider;
212
213     remote_provider = wl_resource_get_user_data(provider_resource);
214
215     if (remote_provider->input_event_filter == event_filter)
216         return;
217
218     remote_provider->input_event_filter = event_filter;
219
220     wl_signal_emit_mutable(&remote_provider->events.set_input_event_filter, remote_provider);
221 }
222
223 static const struct tizen_remote_surface_provider_interface remote_surface_provider_impl =
224 {
225     .destroy = remote_surface_provider_handle_destroy,
226     .offscreen_set = remote_surface_provider_handle_set_offscreen,
227     .set_input_event_filter = remote_surface_provider_handle_set_input_event_filter,
228 };
229
230 static void
231 remote_surface_provider_handle_surface_destroy(struct wl_listener *listener, void *data)
232 {
233     struct ds_tizen_remote_surface_provider *remote_provider;
234
235     remote_provider = wl_container_of(listener, remote_provider, listener.surface_destroy);
236
237     if (remote_provider->listener.surface_destroy.notify) {
238         wl_list_remove(&remote_provider->listener.surface_destroy.link);
239         remote_provider->listener.surface_destroy.notify = NULL;
240     }
241
242     remote_provider->surface = NULL;
243 }
244
245 static void
246 remote_surface_provider_handle_resource_destroy(struct wl_resource *remote_provider_resource)
247 {
248     struct ds_tizen_remote_surface_provider *remote_provider;
249
250     remote_provider = wl_resource_get_user_data(remote_provider_resource);
251
252     ds_inf("remote_surface_provider:%p destroy", remote_provider);
253
254     if (remote_provider->listener.surface_destroy.notify) {
255         wl_list_remove(&remote_provider->listener.surface_destroy.link);
256         remote_provider->listener.surface_destroy.notify = NULL;
257     }
258
259     wl_list_remove(&remote_provider->link);
260
261     wl_signal_emit_mutable(&remote_provider->events.destroy, remote_provider);
262
263     free(remote_provider);
264 }
265
266 static void
267 remote_surface_manager_handle_create_provider(struct wl_client *wl_client,
268     struct wl_resource *remote_surface_client_resource,
269     uint32_t id,
270     struct wl_resource *surface_resource)
271 {
272     struct ds_tizen_remote_surface_client *remote_client;
273     struct ds_tizen_remote_surface_provider *remote_provider;
274     struct ds_surface *surface;
275
276     remote_client = wl_resource_get_user_data(remote_surface_client_resource);
277     surface = ds_surface_from_resource(surface_resource);
278
279     remote_provider = calloc(1, sizeof *remote_provider);
280     if (!remote_provider) {
281         wl_client_post_no_memory(wl_client);
282         return;
283     }
284
285     remote_provider->resource = wl_resource_create(wl_client, &tizen_remote_surface_provider_interface,
286             wl_resource_get_version(remote_client->resource), id);
287     if (!remote_provider->resource) {
288         wl_client_post_no_memory(wl_client);
289         free(remote_provider);
290         return;
291     }
292
293     remote_provider->listener.surface_destroy.notify = remote_surface_provider_handle_surface_destroy;
294     ds_surface_add_destroy_listener(surface, &remote_provider->listener.surface_destroy);
295     remote_provider->surface = surface;
296
297     wl_resource_set_implementation(remote_provider->resource, &remote_surface_provider_impl,
298             remote_provider, remote_surface_provider_handle_resource_destroy);
299
300     ds_inf("remote_surface_provider:%p create", remote_provider);
301
302     wl_signal_init(&remote_provider->events.destroy);
303     wl_signal_init(&remote_provider->events.set_offscreen);
304     wl_signal_init(&remote_provider->events.set_input_event_filter);
305
306     wl_signal_emit_mutable(&remote_client->remote_manager->events.new_provider, remote_provider);
307
308     remote_provider->resource_id = global_resource_id++;
309
310     tizen_remote_surface_provider_send_resource_id(remote_provider->resource, remote_provider->resource_id);
311
312     wl_list_insert(&remote_client->remote_manager->remote_providers, &remote_provider->link);
313 }
314
315 static void
316 remote_surface_handle_destroy(struct wl_client *wl_client,
317     struct wl_resource *resource)
318 {
319     wl_resource_destroy(resource);
320 }
321
322 static void
323 remote_surface_handle_redirect(struct wl_client *wl_client,
324     struct wl_resource *remote_surface_resource)
325 {
326     struct ds_tizen_remote_surface *remote_surface;
327
328     remote_surface = wl_resource_get_user_data(remote_surface_resource);
329
330     remote_surface->redirect = true;
331
332     wl_signal_emit_mutable(&remote_surface->events.set_redirect, remote_surface);
333 }
334
335 static void
336 remote_surface_handle_unredirect(struct wl_client *wl_client,
337     struct wl_resource *remote_surface_resource)
338 {
339     struct ds_tizen_remote_surface *remote_surface;
340
341     remote_surface = wl_resource_get_user_data(remote_surface_resource);
342
343     remote_surface->redirect = false;
344
345     wl_signal_emit_mutable(&remote_surface->events.set_redirect, remote_surface);
346 }
347
348 static void
349 remote_surface_handle_transfer_mouse_event(struct wl_client *wl_client,
350     struct wl_resource *remote_surface_resource,
351     uint32_t event_type, int32_t device, int32_t button,
352     int32_t x, int32_t y, wl_fixed_t radius_x, wl_fixed_t radius_y,
353     wl_fixed_t pressure, wl_fixed_t angle, uint32_t clas, uint32_t subclas,
354     const char *identifier, uint32_t time)
355 {
356     struct ds_tizen_remote_surface *remote_surface;
357     struct ds_tizen_remote_surface_event_transfer_mouse event;
358
359     remote_surface = wl_resource_get_user_data(remote_surface_resource);
360
361     event.remote_surface = remote_surface;
362     event.event_type = event_type;
363     event.device = device;
364     event.button = button;
365     event.x = x;
366     event.y = y;
367     event.radius_x = radius_x;
368     event.radius_y = radius_y;
369     event.pressure = pressure;
370     event.angle = angle;
371     event.clas = clas;
372     event.subclas = subclas;
373     event.identifier = identifier;
374     event.time = time;
375
376     wl_signal_emit_mutable(&remote_surface->events.transfer_mouse_event, &event);
377 }
378
379 static void
380 remote_surface_handle_transfer_mouse_wheel(struct wl_client *wl_client,
381     struct wl_resource *remote_surface_resource,
382     uint32_t direction, int32_t z, uint32_t clas, uint32_t subclas,
383     const char *identifier, uint32_t time)
384 {
385     struct ds_tizen_remote_surface *remote_surface;
386     struct ds_tizen_remote_surface_event_transfer_mouse_wheel event;
387
388     remote_surface = wl_resource_get_user_data(remote_surface_resource);
389
390     event.remote_surface = remote_surface;
391     event.direction = direction;
392     event.z = z;
393     event.clas = clas;
394     event.subclas = subclas;
395     event.identifier = identifier;
396     event.time = time;
397
398     wl_signal_emit_mutable(&remote_surface->events.transfer_mouse_wheel_event, &event);
399 }
400
401 static void
402 remote_surface_handle_transfer_touch_event(struct wl_client *wl_client,
403     struct wl_resource *remote_surface_resource,
404     uint32_t event_type, int32_t device, int32_t button, int32_t x, int32_t y,
405     wl_fixed_t radius_x, wl_fixed_t radius_y, wl_fixed_t pressure, wl_fixed_t angle,
406     uint32_t clas, uint32_t subclas, const char *identifier, uint32_t time)
407 {
408     struct ds_tizen_remote_surface *remote_surface;
409     struct ds_tizen_remote_surface_event_transfer_touch event;
410
411     remote_surface = wl_resource_get_user_data(remote_surface_resource);
412
413     event.remote_surface = remote_surface;
414     event.event_type = event_type;
415     event.device = device;
416     event.button = button;
417     event.x = x;
418     event.y = y;
419     event.radius_x = radius_x;
420     event.radius_y = radius_y;
421     event.pressure = pressure;
422     event.angle = angle;
423     event.clas = clas;
424     event.subclas = subclas;
425     event.identifier = identifier;
426     event.time = time;
427
428     wl_signal_emit_mutable(&remote_surface->events.transfer_touch_event, &event);
429 }
430
431 static void
432 remote_surface_handle_transfer_touch_cancel(struct wl_client *wl_client,
433     struct wl_resource *remote_surface_resource)
434 {
435     struct ds_tizen_remote_surface *remote_surface;
436     struct ds_tizen_remote_surface_event_transfer_touch_cancel event;
437
438     remote_surface = wl_resource_get_user_data(remote_surface_resource);
439
440     event.remote_surface = remote_surface;
441
442     wl_signal_emit_mutable(&remote_surface->events.transfer_touch_cancel_event, &event);
443 }
444
445 static void
446 remote_surface_handle_transfer_key_event(struct wl_client *wl_client,
447     struct wl_resource *remote_surface_resource,
448     uint32_t event_type, int32_t keycode, uint32_t clas, uint32_t subclas,
449     const char *identifier, uint32_t time)
450 {
451     struct ds_tizen_remote_surface *remote_surface;
452     struct ds_tizen_remote_surface_event_transfer_key event;
453
454     remote_surface = wl_resource_get_user_data(remote_surface_resource);
455
456     event.remote_surface = remote_surface;
457     event.event_type = event_type;
458     event.keycode = keycode;
459     event.clas = clas;
460     event.subclas = subclas;
461     event.identifier = identifier;
462     event.time = time;
463
464     wl_signal_emit_mutable(&remote_surface->events.transfer_key_event, &event);
465 }
466
467 static void
468 remote_surface_handle_transfer_visibility(struct wl_client *wl_client,
469     struct wl_resource *remote_surface_resource,
470     uint32_t visibility_type)
471 {
472     struct ds_tizen_remote_surface *remote_surface;
473     struct ds_tizen_remote_surface_event_transfer_visibility event;
474
475     remote_surface = wl_resource_get_user_data(remote_surface_resource);
476
477     event.remote_surface = remote_surface;
478     event.visibility = visibility_type;
479
480     wl_signal_emit_mutable(&remote_surface->events.transfer_visibility_event, &event);
481 }
482
483 static void
484 remote_surface_handle_owner_surface_destroy(struct wl_listener *listener, void *data)
485 {
486     struct ds_tizen_remote_surface *remote_surface;
487
488     remote_surface = wl_container_of(listener, remote_surface, listener.surface_destroy);
489
490     if (remote_surface->listener.owner_surface_destroy.notify) {
491         wl_list_remove(&remote_surface->listener.owner_surface_destroy.link);
492         remote_surface->listener.owner_surface_destroy.notify = NULL;
493     }
494
495     remote_surface->owner_surface = NULL;
496 }
497
498 static void
499 remote_surface_handle_set_owner(struct wl_client *wl_client,
500     struct wl_resource *remote_surface_resource,
501     struct wl_resource *surface_resource)
502 {
503     struct ds_tizen_remote_surface *remote_surface;
504     struct ds_surface *surface;
505
506     remote_surface = wl_resource_get_user_data(remote_surface_resource);
507     surface = ds_surface_from_resource(surface_resource);
508
509     remote_surface->listener.owner_surface_destroy.notify = remote_surface_handle_owner_surface_destroy;
510     ds_surface_add_destroy_listener(surface, &remote_surface->listener.owner_surface_destroy);
511     remote_surface->owner_surface = surface;
512
513     wl_signal_emit_mutable(&remote_surface->events.set_owner, remote_surface);
514 }
515
516 static void
517 remote_region_handle_destroy(struct wl_client *wl_client,
518     struct wl_resource *resource)
519 {
520     wl_resource_destroy(resource);
521 }
522
523 static void
524 remote_region_handle_set_geometry(struct wl_client *wl_client,
525     struct wl_resource *remote_region_resource,
526     int32_t x, int32_t y, int32_t w, int32_t h)
527 {
528     struct ds_tizen_remote_surface_region *remote_region;
529
530     remote_region = wl_resource_get_user_data(remote_region_resource);
531
532     remote_region->x = x;
533     remote_region->y = y;
534     remote_region->w = w;
535     remote_region->h = h;
536
537     wl_signal_emit_mutable(&remote_region->events.set_geometry, remote_region);
538 }
539
540 static const struct tizen_remote_surface_region_interface remote_surface_region_impl =
541 {
542    .destroy = remote_region_handle_destroy,
543    .set_geometry = remote_region_handle_set_geometry,
544 };
545
546 static void
547 remote_surface_region_handle_resource_destroy(struct wl_resource *remote_region_resource)
548 {
549     struct ds_tizen_remote_surface_region *remote_region;
550
551     remote_region = wl_resource_get_user_data(remote_region_resource);
552
553     ds_inf("remote_region:%p destroy", remote_region);
554
555     wl_signal_emit_mutable(&remote_region->events.destroy, remote_region);
556
557     free(remote_region);
558 }
559
560 static void
561 remote_surface_handle_create_region(struct wl_client *wl_client,
562     struct wl_resource *remote_surface_resource,
563     uint32_t id)
564 {
565     struct ds_tizen_remote_surface *remote_surface;
566     struct ds_tizen_remote_surface_region *remote_region;
567
568     remote_surface = wl_resource_get_user_data(remote_surface_resource);
569
570     remote_region = calloc(1, sizeof *remote_region);
571     if (!remote_region) {
572         wl_client_post_no_memory(wl_client);
573         return;
574     }
575
576     remote_region->resource = wl_resource_create(wl_client, &tizen_remote_surface_region_interface,
577             1, id);
578     if (!remote_region->resource) {
579         wl_client_post_no_memory(wl_client);
580         free(remote_region);
581         return;
582     }
583
584     wl_resource_set_implementation(remote_region->resource, &remote_surface_region_impl,
585             remote_region, remote_surface_region_handle_resource_destroy);
586
587     ds_inf("remote_surface_region:%p create", remote_region);
588
589     wl_signal_init(&remote_region->events.destroy);
590     wl_signal_init(&remote_region->events.set_geometry);
591
592     wl_signal_emit_mutable(&remote_surface->events.new_region, remote_region);
593 }
594
595 static void
596 remote_surface_handle_release(struct wl_client *wl_client,
597     struct wl_resource *remote_surface_resource,
598     struct wl_resource *remote_buffer_resource)
599 {
600     struct ds_tizen_remote_surface *remote_surface;
601     struct ds_buffer *buffer;
602     struct ds_tizen_remote_surface_event_buffer_release event;
603
604     remote_surface = wl_resource_get_user_data(remote_surface_resource);
605     buffer = ds_buffer_from_resource(remote_buffer_resource);
606
607     event.remote_surface = remote_surface;
608     event.buffer = buffer;
609
610     wl_signal_emit_mutable(&remote_surface->events.buffer_release, &event);
611 }
612
613 static void
614 remote_surface_handle_set_remote_render(struct wl_client *wl_client,
615     struct wl_resource *remote_surface_resource,
616     uint32_t set)
617 {
618     struct ds_tizen_remote_surface *remote_surface;
619
620     remote_surface = wl_resource_get_user_data(remote_surface_resource);
621
622     if (set > 0)
623         remote_surface->remote_render = true;
624     else
625         remote_surface->remote_render = false;
626
627     wl_signal_emit_mutable(&remote_surface->events.set_remote_render, remote_surface);
628 }
629
630 static void
631 remote_surface_handle_set_changed_buffer_event_filter(struct wl_client *wl_client,
632     struct wl_resource *remote_surface_resource,
633     enum tizen_remote_surface_changed_buffer_event_filter filter)
634 {
635     struct ds_tizen_remote_surface *remote_surface;
636
637     remote_surface = wl_resource_get_user_data(remote_surface_resource);
638
639     remote_surface->changed_buffer_event_filter = filter;
640
641     wl_signal_emit_mutable(&remote_surface->events.set_changed_buffer_event_filter, remote_surface);
642 }
643
644 static void
645 remote_surface_handle_get_current_buffer(struct wl_client *wl_client,
646     struct wl_resource *remote_surface_resource,
647     enum tizen_remote_surface_buffer_type buff_type,
648     uint32_t req_serial)
649 {
650     struct ds_tizen_remote_surface *remote_surface;
651     struct ds_tizen_remote_surface_event_current_buffer event;
652
653     remote_surface = wl_resource_get_user_data(remote_surface_resource);
654
655     event.remote_surface = remote_surface;
656     event.buffer_type = buff_type;
657     event.request_serial = req_serial;
658
659     wl_signal_emit_mutable(&remote_surface->events.get_current_buffer, &event);
660 }
661
662 static const struct tizen_remote_surface_interface remote_surface_impl =
663 {
664    .destroy = remote_surface_handle_destroy,
665    .redirect = remote_surface_handle_redirect,
666    .unredirect = remote_surface_handle_unredirect,
667    .transfer_mouse_event = remote_surface_handle_transfer_mouse_event,
668    .transfer_mouse_wheel = remote_surface_handle_transfer_mouse_wheel,
669    .transfer_touch_event = remote_surface_handle_transfer_touch_event,
670    .transfer_touch_cancel = remote_surface_handle_transfer_touch_cancel,
671    .transfer_key_event = remote_surface_handle_transfer_key_event,
672    .transfer_visibility = remote_surface_handle_transfer_visibility,
673    .set_owner = remote_surface_handle_set_owner,
674    .create_region = remote_surface_handle_create_region,
675    .release = remote_surface_handle_release,
676    .set_remote_render = remote_surface_handle_set_remote_render,
677    .set_changed_buffer_event_filter = remote_surface_handle_set_changed_buffer_event_filter,
678    .get_current_buffer = remote_surface_handle_get_current_buffer,
679 };
680
681 static void
682 remote_surface_handle_surface_destroy(struct wl_listener *listener, void *data)
683 {
684     struct ds_tizen_remote_surface *remote_surface;
685
686     remote_surface = wl_container_of(listener, remote_surface, listener.surface_destroy);
687
688     if (remote_surface->listener.surface_destroy.notify) {
689         wl_list_remove(&remote_surface->listener.surface_destroy.link);
690         remote_surface->listener.surface_destroy.notify = NULL;
691     }
692
693     remote_surface->surface = NULL;
694 }
695
696 static void
697 remote_surface_handle_wl_tbm_resource_destroy(struct wl_listener *listener, void *data)
698 {
699     struct ds_tizen_remote_surface *remote_surface;
700
701     remote_surface = wl_container_of(listener, remote_surface, listener.wl_tbm_resource_destroy);
702
703     if (remote_surface->listener.wl_tbm_resource_destroy.notify) {
704         wl_list_remove(&remote_surface->listener.wl_tbm_resource_destroy.link);
705         remote_surface->listener.wl_tbm_resource_destroy.notify = NULL;
706     }
707
708     remote_surface->wl_tbm_resource = NULL;
709 }
710
711 static void
712 remote_surface_handle_resource_destroy(struct wl_resource *remote_surface_resource)
713 {
714     struct ds_tizen_remote_surface *remote_surface;
715
716     remote_surface = wl_resource_get_user_data(remote_surface_resource);
717
718     ds_inf("remote_surface:%p destroy", remote_surface);
719
720     if (remote_surface->listener.surface_destroy.notify) {
721         wl_list_remove(&remote_surface->listener.surface_destroy.link);
722         remote_surface->listener.surface_destroy.notify = NULL;
723     }
724
725     if (remote_surface->listener.owner_surface_destroy.notify) {
726         wl_list_remove(&remote_surface->listener.owner_surface_destroy.link);
727         remote_surface->listener.owner_surface_destroy.notify = NULL;
728     }
729
730     wl_list_remove(&remote_surface->link);
731
732     wl_signal_emit_mutable(&remote_surface->events.destroy, remote_surface);
733
734     free(remote_surface);
735 }
736
737 static void
738 remote_surface_manager_handle_create_surface(struct wl_client *wl_client,
739     struct wl_resource *remote_surface_client_resource,
740     uint32_t id,
741     uint32_t resource_id,
742     struct wl_resource *wl_tbm_resource)
743 {
744     struct ds_tizen_remote_surface_client *remote_client;
745     struct ds_tizen_remote_surface *remote_surface;
746     struct ds_surface *surface = NULL;
747     struct ds_tizen_remote_surface_provider *remote_provider;
748
749     remote_client = wl_resource_get_user_data(remote_surface_client_resource);
750
751     wl_list_for_each(remote_provider, &remote_client->remote_manager->remote_providers, link) {
752         if (remote_provider->resource_id == resource_id) {
753             surface = remote_provider->surface;
754             break;
755         }
756     }
757
758     if (!surface) {
759         ds_err("fail to find ds_surface from resource_id:%d", resource_id);
760         return;
761     }
762
763     remote_surface = calloc(1, sizeof *remote_surface);
764     if (!remote_surface) {
765         wl_client_post_no_memory(wl_client);
766         return;
767     }
768
769     remote_surface->resource = wl_resource_create(wl_client, &tizen_remote_surface_interface,
770             wl_resource_get_version(remote_client->resource), id);
771     if (!remote_surface->resource) {
772         wl_client_post_no_memory(wl_client);
773         free(remote_surface);
774         return;
775     }
776
777     remote_surface->listener.surface_destroy.notify = remote_surface_handle_surface_destroy;
778     ds_surface_add_destroy_listener(surface, &remote_surface->listener.surface_destroy);
779     remote_surface->surface = surface;
780
781     remote_surface->listener.wl_tbm_resource_destroy.notify = remote_surface_handle_wl_tbm_resource_destroy;
782     wl_resource_add_destroy_listener(wl_tbm_resource, &remote_surface->listener.wl_tbm_resource_destroy);
783     remote_surface->wl_tbm_resource = wl_tbm_resource;
784
785     wl_resource_set_implementation(remote_surface->resource, &remote_surface_impl,
786             remote_surface, remote_surface_handle_resource_destroy);
787
788     ds_inf("remote_surface:%p create", remote_surface);
789
790     wl_signal_init(&remote_surface->events.destroy);
791     wl_signal_init(&remote_surface->events.set_redirect);
792     wl_signal_init(&remote_surface->events.transfer_mouse_event);
793     wl_signal_init(&remote_surface->events.transfer_mouse_wheel_event);
794     wl_signal_init(&remote_surface->events.transfer_touch_event);
795     wl_signal_init(&remote_surface->events.transfer_touch_cancel_event);
796     wl_signal_init(&remote_surface->events.transfer_key_event);
797     wl_signal_init(&remote_surface->events.transfer_visibility_event);
798     wl_signal_init(&remote_surface->events.set_owner);
799     wl_signal_init(&remote_surface->events.new_region);
800     wl_signal_init(&remote_surface->events.buffer_release);
801     wl_signal_init(&remote_surface->events.set_remote_render);
802     wl_signal_init(&remote_surface->events.set_changed_buffer_event_filter);
803     wl_signal_init(&remote_surface->events.get_current_buffer);
804
805     wl_list_insert(&remote_client->remote_manager->remote_surfaces, &remote_surface->link);
806
807     wl_signal_emit_mutable(&remote_client->remote_manager->events.new_surface, remote_surface);
808 }
809
810 static void
811 remote_surface_manager_handle_bind_surface(struct wl_client *wl_client,
812     struct wl_resource *remote_surface_client_resource,
813     struct wl_resource *surface_resource,
814     struct wl_resource *remote_surface_resource)
815 {
816     struct ds_tizen_remote_surface_manager_event_bind_surface event;
817     struct ds_tizen_remote_surface_client *remote_client;
818     struct ds_tizen_remote_surface *remote_surface;
819     struct ds_surface *surface;
820
821     remote_client = wl_resource_get_user_data(remote_surface_client_resource);
822     surface = ds_surface_from_resource(surface_resource);
823     remote_surface = wl_resource_get_user_data(surface_resource);
824
825     event.remote_surface = remote_surface;
826     event.surface = surface;
827
828     wl_signal_emit_mutable(&remote_client->remote_manager->events.bind_surface, &event);
829 }
830
831 static void
832 remote_surface_manager_handle_destroy(struct wl_client *wl_client,
833     struct wl_resource *resource)
834 {
835     wl_resource_destroy(resource);
836 }
837
838 static void
839 remote_surface_manager_handle_create_surface_with_wl_surface(struct wl_client *wl_client,
840     struct wl_resource *remote_client_resource,
841     uint32_t id,
842     uint32_t resource_id,
843     struct wl_resource *wl_tbm_resource,
844     struct wl_resource *surface_resource)
845 {
846     struct ds_tizen_remote_surface_client *remote_client;
847     struct ds_tizen_remote_surface *remote_surface;
848     struct ds_surface *surface = NULL, *owner_surface;
849     struct ds_tizen_remote_surface_provider *remote_provider;
850
851     remote_client = wl_resource_get_user_data(remote_client_resource);
852     owner_surface = ds_surface_from_resource(surface_resource);
853
854     wl_list_for_each(remote_provider, &remote_client->remote_manager->remote_providers, link) {
855         if (remote_provider->resource_id == resource_id) {
856             surface = remote_provider->surface;
857             break;
858         }
859     }
860
861     if (!surface) {
862         ds_err("fail to find ds_surface from resource_id:%d", resource_id);
863         return;
864     }
865
866     remote_surface = calloc(1, sizeof *remote_surface);
867     if (!remote_surface) {
868         wl_client_post_no_memory(wl_client);
869         return;
870     }
871
872     remote_surface->resource = wl_resource_create(wl_client, &tizen_remote_surface_interface,
873             wl_resource_get_version(remote_client->resource), id);
874     if (!remote_surface->resource) {
875         wl_client_post_no_memory(wl_client);
876         free(remote_surface);
877         return;
878     }
879
880     remote_surface->listener.owner_surface_destroy.notify = remote_surface_handle_owner_surface_destroy;
881     ds_surface_add_destroy_listener(owner_surface, &remote_surface->listener.owner_surface_destroy);
882     remote_surface->owner_surface = owner_surface;
883
884     remote_surface->listener.surface_destroy.notify = remote_surface_handle_surface_destroy;
885     ds_surface_add_destroy_listener(surface, &remote_surface->listener.surface_destroy);
886     remote_surface->surface = surface;
887
888     remote_surface->listener.wl_tbm_resource_destroy.notify = remote_surface_handle_wl_tbm_resource_destroy;
889     wl_resource_add_destroy_listener(wl_tbm_resource, &remote_surface->listener.wl_tbm_resource_destroy);
890     remote_surface->wl_tbm_resource = wl_tbm_resource;
891
892     wl_resource_set_implementation(remote_surface->resource, &remote_surface_impl,
893             remote_surface, remote_surface_handle_resource_destroy);
894
895     ds_inf("remote_surface:%p create", remote_surface);
896
897     wl_signal_init(&remote_surface->events.destroy);
898     wl_signal_init(&remote_surface->events.set_redirect);
899     wl_signal_init(&remote_surface->events.transfer_mouse_event);
900     wl_signal_init(&remote_surface->events.transfer_mouse_wheel_event);
901     wl_signal_init(&remote_surface->events.transfer_touch_event);
902     wl_signal_init(&remote_surface->events.transfer_touch_cancel_event);
903     wl_signal_init(&remote_surface->events.transfer_key_event);
904     wl_signal_init(&remote_surface->events.transfer_visibility_event);
905     wl_signal_init(&remote_surface->events.set_owner);
906     wl_signal_init(&remote_surface->events.new_region);
907     wl_signal_init(&remote_surface->events.buffer_release);
908     wl_signal_init(&remote_surface->events.set_remote_render);
909     wl_signal_init(&remote_surface->events.set_changed_buffer_event_filter);
910     wl_signal_init(&remote_surface->events.get_current_buffer);
911
912     wl_list_insert(&remote_client->remote_manager->remote_surfaces, &remote_surface->link);
913
914     wl_signal_emit_mutable(&remote_client->remote_manager->events.new_surface, remote_surface);
915     wl_signal_emit_mutable(&remote_surface->events.set_owner, remote_surface);
916 }
917
918 static const struct tizen_remote_surface_manager_interface remote_surface_manager_impl =
919 {
920     .create_provider = remote_surface_manager_handle_create_provider,
921     .create_surface = remote_surface_manager_handle_create_surface,
922     .bind_surface = remote_surface_manager_handle_bind_surface,
923     .destroy = remote_surface_manager_handle_destroy,
924     .create_surface_with_wl_surface = remote_surface_manager_handle_create_surface_with_wl_surface,
925 };
926
927 static void
928 tizen_remote_surface_client_handle_resource_destroy(struct wl_resource *resource)
929 {
930     struct ds_tizen_remote_surface_client *remote_client;
931
932     remote_client = wl_resource_get_user_data(resource);
933
934     ds_inf("_tizen_remote_surface_client_handle_destroy (client:%p)", remote_client);
935
936     free(remote_client);
937 }
938
939 static void
940 remote_surface_manager_bind(struct wl_client *wl_client, void *data, uint32_t version,
941          uint32_t id)
942 {
943     struct ds_tizen_remote_surface_manager *remote_manager = data;
944     struct ds_tizen_remote_surface_client *remote_client;
945
946     remote_client = calloc(1, sizeof *remote_client);
947     if (!remote_client) {
948         ds_err("calloc() failed. tizen_remote_surface_client");
949         wl_client_post_no_memory(wl_client);
950         return;
951     }
952
953     ds_inf("tizen_remote_surface_client binds. (client:%p)", remote_client);
954
955     remote_client->remote_manager = remote_manager;
956     remote_client->wl_client = wl_client;
957
958     remote_client->resource = wl_resource_create(wl_client, &tizen_remote_surface_manager_interface,
959             MIN(version, TIZEN_REMOTE_SURFACE_VERSION), id);
960     if (!remote_client->resource) {
961         ds_err("tizen_remote_surface : wl_resource_create() failed.");
962         free(remote_client);
963         wl_client_post_no_memory(wl_client);
964         return;
965     }
966
967     wl_resource_set_implementation(remote_client->resource, &remote_surface_manager_impl,
968             remote_client, tizen_remote_surface_client_handle_resource_destroy);
969
970     wl_signal_init(&remote_client->events.destroy);
971 }
972
973 static void
974 remote_surface_manager_handle_display_destroy(struct wl_listener *listener, void *data)
975 {
976     struct ds_tizen_remote_surface_manager *remote_manager;
977
978     remote_manager = wl_container_of(listener, remote_manager, destroy);
979
980     ds_inf("Global destroy: remote_surface_manager(%p)", remote_manager);
981
982     wl_signal_emit_mutable(&remote_manager->events.destroy, remote_manager);
983     wl_list_remove(&remote_manager->destroy.link);
984     wl_global_destroy(remote_manager->global);
985     free(remote_manager);
986 }
987
988 WL_EXPORT struct ds_tizen_remote_surface_manager *
989 ds_tizen_remote_surface_manager_create(struct wl_display *display)
990 {
991     struct ds_tizen_remote_surface_manager *remote_manager;
992
993     remote_manager = calloc(1, sizeof *remote_manager);
994     if (!remote_manager) {
995         ds_err("calloc() failed.");
996         return NULL;
997     }
998
999     remote_manager->global = wl_global_create(display, &tizen_remote_surface_manager_interface,
1000             TIZEN_REMOTE_SURFACE_VERSION, remote_manager, remote_surface_manager_bind);
1001     if (!remote_manager->global) {
1002         ds_err("wl_global_create() failed. tizen_remote_surface_interface");
1003         free(remote_manager);
1004         return NULL;
1005     }
1006
1007     remote_manager->destroy.notify = remote_surface_manager_handle_display_destroy;
1008     wl_display_add_destroy_listener(display, &remote_manager->destroy);
1009
1010     wl_list_init(&remote_manager->remote_providers);
1011     wl_list_init(&remote_manager->remote_surfaces);
1012
1013     wl_signal_init(&remote_manager->events.destroy);
1014     wl_signal_init(&remote_manager->events.new_provider);
1015     wl_signal_init(&remote_manager->events.new_surface);
1016     wl_signal_init(&remote_manager->events.bind_surface);
1017
1018     ds_inf("Global created: tizen_remote_surface_manager(%p)", remote_manager);
1019
1020     return remote_manager;
1021 }
1022
1023 WL_EXPORT void
1024 ds_tizen_remote_surface_manager_add_destroy_listener(
1025         struct ds_tizen_remote_surface_manager *remote_manager,
1026         struct wl_listener *listener)
1027 {
1028     wl_signal_add(&remote_manager->events.destroy, listener);
1029 }
1030
1031 WL_EXPORT void
1032 ds_tizen_remote_surface_manager_add_new_provider_listener(
1033         struct ds_tizen_remote_surface_manager *remote_manager,
1034         struct wl_listener *listener)
1035 {
1036     wl_signal_add(&remote_manager->events.new_provider, listener);
1037 }
1038
1039 WL_EXPORT void
1040 ds_tizen_remote_surface_manager_add_new_surface_listener(
1041         struct ds_tizen_remote_surface_manager *remote_manager,
1042         struct wl_listener *listener)
1043 {
1044     wl_signal_add(&remote_manager->events.new_surface, listener);
1045 }
1046
1047 WL_EXPORT void
1048 ds_tizen_remote_surface_manager_add_bind_surface_listener(
1049         struct ds_tizen_remote_surface_manager *remote_manager,
1050         struct wl_listener *listener)
1051 {
1052     wl_signal_add(&remote_manager->events.bind_surface, listener);
1053 }
1054
1055 WL_EXPORT void
1056 ds_tizen_remote_surface_provider_add_destroy_listener(
1057         struct ds_tizen_remote_surface_provider *remote_provider,
1058         struct wl_listener *listener)
1059 {
1060     wl_signal_add(&remote_provider->events.destroy, listener);
1061 }
1062
1063 WL_EXPORT void
1064 ds_tizen_remote_surface_provider_add_set_offscreen_listener(
1065         struct ds_tizen_remote_surface_provider *remote_provider,
1066         struct wl_listener *listener)
1067 {
1068     wl_signal_add(&remote_provider->events.set_offscreen, listener);
1069 }
1070
1071 WL_EXPORT void
1072 ds_tizen_remote_surface_provider_add_set_input_event_filter_listener(
1073         struct ds_tizen_remote_surface_provider *remote_provider,
1074         struct wl_listener *listener)
1075 {
1076     wl_signal_add(&remote_provider->events.set_input_event_filter, listener);
1077 }
1078
1079 WL_EXPORT bool
1080 ds_tizen_remote_surface_provider_get_offscreen(
1081         struct ds_tizen_remote_surface_provider *remote_provider)
1082 {
1083     return remote_provider->offscreen;
1084 }
1085
1086 WL_EXPORT uint32_t
1087 ds_tizen_remote_surface_provider_get_input_event_filter(
1088         struct ds_tizen_remote_surface_provider *remote_provider)
1089 {
1090     return remote_provider->input_event_filter;
1091 }
1092
1093 WL_EXPORT void
1094 ds_tizen_remote_surface_provider_send_visibility(
1095         struct ds_tizen_remote_surface_provider *remote_provider,
1096         enum ds_tizen_remote_surface_visibility_type visibility)
1097 {
1098     tizen_remote_surface_provider_send_visibility(remote_provider->resource,
1099             visibility);
1100 }
1101
1102 WL_EXPORT void
1103 ds_tizen_remote_surface_add_destroy_listener(
1104         struct ds_tizen_remote_surface *remote_surface,
1105         struct wl_listener *listener)
1106 {
1107     wl_signal_add(&remote_surface->events.destroy, listener);
1108 }
1109
1110 struct wl_resource *
1111 ds_tizen_remote_surface_get_wl_tbm_resource(
1112         struct ds_tizen_remote_surface *remote_surface)
1113 {
1114     return remote_surface->wl_tbm_resource;
1115 }
1116
1117 WL_EXPORT void
1118 ds_tizen_remote_surface_add_set_redirect_listener(
1119         struct ds_tizen_remote_surface *remote_surface,
1120         struct wl_listener *listener)
1121 {
1122     wl_signal_add(&remote_surface->events.set_redirect, listener);
1123 }
1124
1125 WL_EXPORT bool
1126 ds_tizen_remote_surface_get_redirect(
1127         struct ds_tizen_remote_surface *remote_surface)
1128 {
1129     return remote_surface->redirect;
1130 }
1131
1132 WL_EXPORT void
1133 ds_tizen_remote_surface_add_set_owner_listener(
1134         struct ds_tizen_remote_surface *remote_surface,
1135         struct wl_listener *listener)
1136 {
1137     wl_signal_add(&remote_surface->events.set_owner, listener);
1138 }
1139
1140 WL_EXPORT struct ds_surface *
1141 ds_tizen_remote_surface_get_owner(
1142         struct ds_tizen_remote_surface *remote_surface)
1143 {
1144     return remote_surface->owner_surface;
1145 }
1146
1147 WL_EXPORT void
1148 ds_tizen_remote_surface_add_buffer_release_listener(
1149         struct ds_tizen_remote_surface *remote_surface,
1150         struct wl_listener *listener)
1151 {
1152     wl_signal_add(&remote_surface->events.buffer_release, listener);
1153 }
1154
1155 WL_EXPORT void
1156 ds_tizen_remote_surface_add_set_remote_render_listener(
1157         struct ds_tizen_remote_surface *remote_surface,
1158         struct wl_listener *listener)
1159 {
1160     wl_signal_add(&remote_surface->events.set_remote_render, listener);
1161 }
1162
1163 WL_EXPORT bool
1164 ds_tizen_remote_surface_get_remote_render(
1165         struct ds_tizen_remote_surface *remote_surface)
1166 {
1167     return remote_surface->remote_render;
1168 }
1169
1170 WL_EXPORT void
1171 ds_tizen_remote_surface_add_set_changed_buffer_event_filter_listener(
1172         struct ds_tizen_remote_surface *remote_surface,
1173         struct wl_listener *listener)
1174 {
1175     wl_signal_add(&remote_surface->events.set_changed_buffer_event_filter, listener);
1176 }
1177
1178 WL_EXPORT uint32_t
1179 ds_tizen_remote_surface_get_changed_buffer_event_filter(
1180         struct ds_tizen_remote_surface *remote_surface,
1181         struct wl_listener *listener)
1182 {
1183     return remote_surface->changed_buffer_event_filter;
1184 }
1185
1186 WL_EXPORT void
1187 ds_tizen_remote_surface_add_get_current_buffer_listener(
1188         struct ds_tizen_remote_surface *remote_surface,
1189         struct wl_listener *listener)
1190 {
1191     wl_signal_add(&remote_surface->events.get_current_buffer, listener);
1192 }
1193
1194 WL_EXPORT void
1195 ds_tizen_remote_surface_send_changed_buffer(
1196         struct ds_tizen_remote_surface *remote_surface,
1197         struct ds_buffer *buffer,
1198         uint32_t time,
1199         struct wl_array *options)
1200 {
1201     int version;
1202     struct ds_tbm_client_buffer *tbm_client_buffer;
1203     struct wl_resource *buffer_resource;
1204
1205     version = wl_resource_get_version(remote_surface->resource);
1206
1207     tbm_client_buffer = ds_tbm_client_buffer_from_buffer(buffer);
1208     if (!tbm_client_buffer) {
1209         ds_err("not support buffer");
1210         return;
1211     }
1212
1213     buffer_resource = ds_buffer_get_resource(buffer);
1214     if (!buffer_resource) {
1215         ds_err("buffer resource is null");
1216         return;
1217     }
1218
1219     if (version >= TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION) {
1220         tizen_remote_surface_send_changed_buffer(remote_surface->resource,
1221                 TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM,
1222                 buffer_resource,
1223                 remote_surface_dummy_fd_get(),
1224                 0,
1225                 time,
1226                 options);
1227     } else {
1228         tizen_remote_surface_send_update_buffer(remote_surface->resource,
1229                 buffer_resource,
1230                 time);
1231     }
1232 }
1233
1234 WL_EXPORT void
1235 ds_tizen_remote_surface_send_changed_buffer_image_file(
1236         struct ds_tizen_remote_surface *remote_surface,
1237         int image_file_fd,
1238         int image_file_size,
1239         uint32_t time,
1240         struct wl_array *options)
1241 {
1242     int version;
1243
1244     version = wl_resource_get_version(remote_surface->resource);
1245
1246     if (version < TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION) {
1247         ds_err("not support remote_surface:%p version:%d", remote_surface, version);
1248         return;
1249     }
1250
1251     tizen_remote_surface_send_changed_buffer(remote_surface->resource,
1252             TIZEN_REMOTE_SURFACE_BUFFER_TYPE_IMAGE_FILE,
1253             NULL,
1254             image_file_fd,
1255             image_file_size,
1256             time,
1257             options);
1258 }
1259
1260 WL_EXPORT void
1261 ds_tizen_remote_surface_send_missing(
1262         struct ds_tizen_remote_surface *remote_surface)
1263 {
1264     tizen_remote_surface_send_missing(remote_surface->resource);
1265 }
1266
1267 WL_EXPORT void
1268 ds_tizen_remote_surface_send_input_event_filter(
1269         struct ds_tizen_remote_surface *remote_surface,
1270         uint32_t input_event_filter)
1271 {
1272     tizen_remote_surface_send_input_event_filter(remote_surface->resource,
1273             input_event_filter);
1274 }
1275
1276 WL_EXPORT void
1277 ds_tizen_remote_surface_add_new_region_listener(
1278         struct ds_tizen_remote_surface *remote_surface,
1279         struct wl_listener *listener)
1280 {
1281     wl_signal_add(&remote_surface->events.new_region, listener);
1282 }
1283
1284 WL_EXPORT void
1285 ds_tizen_remote_surface_region_add_destroy_listener(
1286         struct ds_tizen_remote_surface_region *remote_region,
1287         struct wl_listener *listener)
1288 {
1289     wl_signal_add(&remote_region->events.destroy, listener);
1290 }
1291
1292 WL_EXPORT void
1293 ds_tizen_remote_surface_region_add_set_geometry_listener(
1294         struct ds_tizen_remote_surface_region *remote_region,
1295         struct wl_listener *listener)
1296 {
1297     wl_signal_add(&remote_region->events.set_geometry, listener);
1298 }
1299
1300 WL_EXPORT void
1301 ds_tizen_remote_surface_region_get_geometry(
1302         struct ds_tizen_remote_surface_region *remote_region,
1303         int32_t *x,int32_t *y, int32_t *w, int32_t *h)
1304 {
1305     if (x) *x = remote_region->x;
1306     if (y) *y = remote_region->y;
1307     if (w) *w = remote_region->w;
1308     if (h) *h = remote_region->h;
1309 }