2 #include "e_policy_wl.h"
3 #ifdef HAVE_REMOTE_SURFACE
4 #include <tizen-remote-surface-server-protocol.h>
5 #endif /* HAVE_REMOTE_SURFACE */
6 #include <tbm_surface.h>
7 #include <tbm_surface_internal.h>
8 #include <wayland-tbm-server.h>
9 #include <tizen-extension-server-protocol.h>
13 #define RSMINF(f, cp, ec, obj, ptr, x...) \
17 INF("EWL|%20.20s| | |%10.10s|%p|"f,\
18 "RSM", (obj), (ptr), ##x); \
20 INF("EWL|%20.20s|win:0x%08zx|ec:%8p|%10.10s|%p|"f, \
22 (e_client_util_win_get(ec)), \
29 #define RSMDBG(f, cp, ec, obj, ptr, x...) \
33 DBG("EWL|%20.20s| | |%10.10s|%p|"f,\
34 "RSM", (obj), (ptr), ##x); \
36 DBG("EWL|%20.20s|win:0x%08zx|ec:%8p|%10.10s|%p|"f, \
38 (e_client_util_win_get(ec)), \
45 #define container_of(ptr, type, member) \
47 const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
48 (type *)( (char *)__mptr - offsetof(type,member) ); \
51 E_API int E_EVENT_REMOTE_SURFACE_PROVIDER_VISIBILITY_CHANGE = -1;
53 #ifdef HAVE_REMOTE_SURFACE
54 typedef struct _E_Comp_Wl_Remote_Manager E_Comp_Wl_Remote_Manager;
55 typedef struct _E_Comp_Wl_Remote_Common E_Comp_Wl_Remote_Common;
56 typedef struct _E_Comp_Wl_Remote_Provider E_Comp_Wl_Remote_Provider;
57 typedef struct _E_Comp_Wl_Remote_Source E_Comp_Wl_Remote_Source;
58 typedef struct _E_Comp_Wl_Remote_Surface E_Comp_Wl_Remote_Surface;
59 typedef struct _E_Comp_Wl_Remote_Region E_Comp_Wl_Remote_Region;
60 typedef struct _E_Comp_Wl_Remote_Buffer E_Comp_Wl_Remote_Buffer;
62 struct _E_Comp_Wl_Remote_Manager
64 struct wl_global *global;
66 Eina_Hash *provider_hash;
67 Eina_Hash *surface_hash;
68 Eina_Hash *source_hash;
69 Eina_Hash *bind_surface_hash;
70 Eina_List *event_hdlrs;
71 Eina_List *client_hooks;
72 Eina_List *process_hooks;
74 int dummy_fd; /* tizen_remote_surface@chagned_buffer need valid fd when it send tbm surface */
77 /* common structure of provider and source */
78 struct _E_Comp_Wl_Remote_Common
83 Eina_Bool is_offscreen;
84 Eina_Bool ignore_output_transform;
88 struct _E_Comp_Wl_Remote_Provider
90 E_Comp_Wl_Remote_Common common;
92 struct wl_resource *resource;
94 E_Comp_Wl_Remote_Surface *onscreen_parent;
98 uint32_t input_event_filter;
102 /* normal UI client */
103 struct _E_Comp_Wl_Remote_Source
105 E_Comp_Wl_Remote_Common common;
107 E_Comp_Wl_Buffer_Ref buffer_ref;
108 const char *image_path;
115 Eina_Bool defer_img_save;
118 /* widget viewer or task-manager client */
119 struct _E_Comp_Wl_Remote_Surface
121 struct wl_resource *resource;
122 struct wl_resource *wl_tbm;
123 struct wl_listener tbm_destroy_listener;
125 E_Comp_Wl_Remote_Provider *provider;
126 E_Comp_Wl_Remote_Source *source;
135 Eina_Bool remote_render;
139 Eina_List *send_remote_bufs;
144 enum tizen_remote_surface_changed_buffer_event_filter filter;
145 } changed_buff_ev_filter;
150 enum tizen_remote_surface_buffer_type type;
157 struct _E_Comp_Wl_Remote_Region
159 struct wl_resource *resource;
161 E_Comp_Wl_Remote_Surface *remote_surface;
162 Eina_Rectangle geometry;
166 struct _E_Comp_Wl_Remote_Buffer
168 E_Comp_Wl_Buffer_Ref ref;
169 struct wl_resource *resource;
170 struct wl_listener destroy_listener;
172 E_Comp_Wl_Remote_Surface *remote_surface;
175 static E_Comp_Wl_Remote_Manager *_rsm = NULL;
177 static void _e_comp_wl_remote_surface_state_buffer_set(E_Comp_Wl_Surface_State *state, E_Comp_Wl_Buffer *buffer);
178 static void _e_comp_wl_remote_buffer_cb_destroy(struct wl_listener *listener, void *data);
179 static E_Comp_Wl_Remote_Buffer *_e_comp_wl_remote_buffer_get(E_Comp_Wl_Remote_Surface *remote_surface,
180 struct wl_resource *remote_buffer_resource);
181 static void _remote_surface_region_clear(E_Comp_Wl_Remote_Surface *remote_surface);
182 static void _remote_surface_ignore_output_transform_send(E_Comp_Wl_Remote_Common *common);
183 static void _remote_source_save_start(E_Comp_Wl_Remote_Source *source);
186 _device_get_by_identifier(const char *identifier)
188 Evas_Device *dev = NULL;
189 const Eina_List *devices, *l;
191 devices = evas_device_list(e_comp->evas, NULL);
192 EINA_LIST_FOREACH(devices, l, dev)
194 if (!e_util_strcmp(identifier, evas_device_description_get(dev)))
202 _remote_region_mirror_clear(E_Comp_Wl_Remote_Region *region)
205 if (!region->mirror) return;
207 evas_object_del(region->mirror);
211 _remote_provider_rect_add(E_Comp_Wl_Remote_Provider *provider, Eina_Rectangle *rect)
215 ec = provider->common.ec;
217 if (!ec->comp_data) return;
219 ec->comp_data->remote_surface.regions =
220 eina_list_remove(ec->comp_data->remote_surface.regions,
222 ec->comp_data->remote_surface.regions =
223 eina_list_append(ec->comp_data->remote_surface.regions,
228 _remote_provider_rect_del(E_Comp_Wl_Remote_Provider *provider, Eina_Rectangle *rect)
232 ec = provider->common.ec;
234 if (!ec->comp_data) return;
236 ec->comp_data->remote_surface.regions =
237 eina_list_remove(ec->comp_data->remote_surface.regions,
242 _remote_provider_rect_clear(E_Comp_Wl_Remote_Provider *provider)
246 ec = provider->common.ec;
248 if (!ec->comp_data) return;
250 /* TODO : remove it from here after supporting multiple onscreen surface */
251 _remote_surface_region_clear(provider->onscreen_parent);
253 ec->comp_data->remote_surface.regions =
254 eina_list_remove_list(ec->comp_data->remote_surface.regions,
255 ec->comp_data->remote_surface.regions);
259 _remote_provider_onscreen_parent_set(E_Comp_Wl_Remote_Provider *provider, E_Comp_Wl_Remote_Surface *parent)
261 E_Comp_Wl_Remote_Region *region;
264 if (!provider) return;
265 if ((parent) && !(parent->owner)) return;
266 if (provider->onscreen_parent == parent) return;
268 _remote_provider_rect_clear(provider);
270 provider->onscreen_parent = parent;
271 provider->common.ec->comp_data->remote_surface.onscreen_parent = NULL;
273 RSMDBG("set onscreen_parent %p(ec:%p)",
274 provider->common.ec->pixmap, provider->common.ec,
275 "PROVIDER", provider,
276 parent, parent? parent->owner:NULL);
280 EINA_LIST_FOREACH(provider->onscreen_parent->regions, l, region)
282 _remote_provider_rect_add(provider, ®ion->geometry);
285 provider->common.ec->comp_data->remote_surface.onscreen_parent = parent->owner;
290 _remote_provider_onscreen_parent_calculate(E_Comp_Wl_Remote_Provider *provider)
293 E_Client *ec, *_ec, *parent = NULL;
294 E_Comp_Wl_Remote_Surface *surface;
295 E_Comp_Wl_Client_Data *cdata;
297 if (!provider) return;
299 ec = provider->common.ec;
301 if (!ec->comp_data) return;
302 if (!provider->common.surfaces) return;
304 o = evas_object_top_get(e_comp->evas);
305 for (; o; o = evas_object_below_get(o))
307 _ec = evas_object_data_get(o, "E_Client");
309 if (_ec == ec) continue;
311 if ((surface = eina_hash_find(_rsm->surface_hash, &_ec)))
313 if (surface->provider != provider) continue;
314 if (!surface->visible) continue;
316 if (e_object_is_del(E_OBJECT(_ec))) continue;
317 if (e_client_util_ignored_get(_ec)) continue;
318 if (_ec->zone != ec->zone) continue;
319 if (!_ec->frame) continue;
320 if (!_ec->visible) continue;
321 if (_ec->visibility.skip) continue;
322 if ((_ec->visibility.obscured != E_VISIBILITY_UNOBSCURED) &&
323 (_ec->visibility.obscured != E_VISIBILITY_PARTIALLY_OBSCURED))
326 /* if _ec is subsurface, skip this */
327 cdata = (E_Comp_Wl_Client_Data *)_ec->comp_data;
328 if (cdata && cdata->sub.data) continue;
330 if (!E_INTERSECTS(_ec->x, _ec->y, _ec->w, _ec->h, ec->zone->x, ec->zone->y, ec->zone->w, ec->zone->h))
340 surface = eina_hash_find(_rsm->surface_hash, &parent);
342 _remote_provider_onscreen_parent_set(provider, surface);
346 _remote_provider_offscreen_set(E_Comp_Wl_Remote_Provider* provider, Eina_Bool set)
350 EINA_SAFETY_ON_NULL_RETURN(provider);
351 EINA_SAFETY_ON_NULL_RETURN(provider->common.ec);
353 ec = provider->common.ec;
355 if (e_object_is_del(E_OBJECT(ec))) return;
359 provider->common.is_offscreen = set;
360 ec->ignored = EINA_TRUE;
362 //TODO: consider what happens if it's not normal client such as subsurface client
363 //TODO: save original values
364 if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.unmap))
366 ELOGF("COMP", "Call shell.unmap by rsm", ec);
367 ec->comp_data->shell.unmap(ec->comp_data->shell.surface);
371 ec->visible = EINA_FALSE;
372 evas_object_hide(ec->frame);
373 ec->comp_data->mapped = 0;
376 ec->icccm.accepts_focus = ec->icccm.take_focus = ec->want_focus = EINA_FALSE;
377 ec->placed = EINA_TRUE;
378 e_client_visibility_skip_set(ec, EINA_TRUE);
380 _remote_provider_onscreen_parent_calculate(provider);
384 e_client_visibility_skip_set(ec, EINA_FALSE);
385 provider->common.is_offscreen = set;
386 ec->icccm.accepts_focus = ec->icccm.take_focus = ec->want_focus = EINA_TRUE;
387 ec->placed = EINA_FALSE;
389 _remote_provider_onscreen_parent_set(provider, NULL);
391 e_comp_wl_surface_commit(ec);
394 _remote_surface_ignore_output_transform_send(&provider->common);
396 RSMINF("%s offscreen",
398 "PROVIDER", provider, set? "Set":"Unset");
402 _remote_provider_visible_event_free(void *data EINA_UNUSED, E_Event_Remote_Surface_Provider *ev)
404 e_object_unref(E_OBJECT(ev->ec));
409 _remote_provider_visible_event_send(E_Comp_Wl_Remote_Provider *provider)
411 E_Event_Remote_Surface_Provider *ev;
413 if (e_object_is_del(E_OBJECT(provider->common.ec))) return;
415 ev = E_NEW(E_Event_Remote_Surface_Provider, 1);
418 ev->ec = provider->common.ec;
419 e_object_ref(E_OBJECT(provider->common.ec));
420 ecore_event_add(E_EVENT_REMOTE_SURFACE_PROVIDER_VISIBILITY_CHANGE, ev, (Ecore_End_Cb)_remote_provider_visible_event_free, NULL);
424 _remote_provider_visible_set(E_Comp_Wl_Remote_Provider *provider, Eina_Bool set)
426 EINA_SAFETY_ON_NULL_RETURN(provider);
430 provider->vis_ref ++;
431 RSMDBG("Count up vis_ref:%d",
432 provider->common.ec->pixmap, provider->common.ec,
433 "PROVIDER", provider, provider->vis_ref);
435 if (provider->vis_ref == 1)
437 provider->common.ec->visibility.obscured = E_VISIBILITY_UNOBSCURED;
439 _remote_provider_visible_event_send(provider);
440 e_policy_client_visibility_send(provider->common.ec);
442 tizen_remote_surface_provider_send_visibility
444 TIZEN_REMOTE_SURFACE_PROVIDER_VISIBILITY_TYPE_VISIBLE);
449 provider->vis_ref --;
450 RSMDBG("Count down vis_ref:%d",
451 provider->common.ec->pixmap, provider->common.ec,
452 "PROVIDER", provider, provider->vis_ref);
454 if (provider->vis_ref == 0)
456 provider->common.ec->visibility.obscured = E_VISIBILITY_FULLY_OBSCURED;
458 _remote_provider_visible_event_send(provider);
459 e_policy_client_visibility_send(provider->common.ec);
461 tizen_remote_surface_provider_send_visibility
463 TIZEN_REMOTE_SURFACE_PROVIDER_VISIBILITY_TYPE_INVISIBLE);
465 if (provider->buffer_mode)
466 e_pixmap_buffer_clear(provider->common.ec->pixmap, EINA_TRUE);
470 _remote_provider_onscreen_parent_calculate(provider);
474 _remote_provider_client_set(E_Client *ec, Eina_Bool set)
477 if ((e_object_is_del(E_OBJECT(ec)))) return;
479 ec->remote_surface.provider = set;
482 static E_Comp_Wl_Remote_Provider *
483 _remote_provider_find(E_Client *ec)
485 E_Comp_Wl_Remote_Provider *provider;
487 EINA_SAFETY_ON_NULL_RETURN_VAL(_rsm, NULL);
488 EINA_SAFETY_ON_NULL_RETURN_VAL(_rsm->provider_hash, NULL);
490 provider = eina_hash_find(_rsm->provider_hash, &ec);
494 /* true : given buffer type can be delivered to the client
495 * false: the client wants to filter given buffer type, thus changed_buffer
496 * event for this type of buffer will not be sent to the client.
499 _remote_surface_changed_buff_ev_filter_check(E_Comp_Wl_Remote_Surface *rs,
500 enum tizen_remote_surface_buffer_type buff_type)
502 Eina_Bool res = EINA_TRUE;
504 if (rs->changed_buff_ev_filter.use)
508 case TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM:
509 if (rs->changed_buff_ev_filter.filter & TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_TBM)
512 case TIZEN_REMOTE_SURFACE_BUFFER_TYPE_IMAGE_FILE:
513 if (rs->changed_buff_ev_filter.filter & TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_IMAGE_FILE)
525 _remote_surface_changed_buff_protocol_send(E_Comp_Wl_Remote_Surface *rs,
526 enum tizen_remote_surface_buffer_type buff_type,
528 unsigned int img_file_size,
530 E_Comp_Wl_Buffer *buff)
532 E_Comp_Wl_Remote_Common *common = NULL;
533 E_Client *src_ec = NULL;
534 struct wl_resource *tbm = NULL;
535 Eina_Bool send = EINA_FALSE;
536 struct wl_array opts;
537 Eina_Bool add_opts = EINA_FALSE;
540 struct wl_resource *rbuff_res = NULL;
541 E_Comp_Wl_Remote_Buffer *rbuff = NULL;
545 common = &rs->provider->common;
546 src_ec = rs->provider->common.ec;
550 common = &rs->source->common;
551 src_ec = rs->source->common.ec;
554 if (!common || !src_ec)
556 ERR("CHANGED_BUFF: no common(%p) or src_ec(%p)", common, src_ec);
560 DBG("CHANGED_BUFF: src_ec(%p) bind_ec(%p) buffer_transform(%d)",
561 src_ec, rs->bind_ec, e_comp_wl_output_buffer_transform_get(src_ec));
563 /* if unbinded, buffer_transform should be 0 for consumer to composite buffers.
564 * Otherwise, we skip sending a change_buffer event because buffer is not ready.
566 if (!rs->bind_ec && e_comp_wl_output_buffer_transform_get(src_ec))
568 RSMINF("CHANGED_BUFF skiped: buffer not ready", NULL, NULL, "SURFACE", rs);
572 send = _remote_surface_changed_buff_ev_filter_check(rs, buff_type);
577 rbuff_res = e_comp_wl_tbm_remote_buffer_get(rs->wl_tbm, buff->resource);
578 EINA_SAFETY_ON_NULL_RETURN_VAL(rbuff_res, EINA_FALSE);
580 rbuff = _e_comp_wl_remote_buffer_get(rs, rbuff_res);
581 EINA_SAFETY_ON_NULL_RETURN_VAL(rbuff, EINA_FALSE);
583 tbm = rbuff->resource;
584 EINA_SAFETY_ON_NULL_RETURN_VAL(tbm, EINA_FALSE);
587 (rs->version >= 2)) /* WORKAROUND for 3.0: old version wayland-scanner can't generation since macro. TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION */
588 e_comp_wl_buffer_reference(&rbuff->ref, buff);
591 if (rs->version >= TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION)
593 if (rs->req_curr_buff.set)
595 /* example of option list:
596 * [0] "curr_buff_req_serial"
600 wl_array_init(&opts);
601 p = wl_array_add(&opts, 21);
602 if (p) strncpy(p, "curr_buff_req_serial", 21);
604 snprintf(tmp, sizeof(tmp), "%u", rs->req_curr_buff.serial);
605 len = strlen(tmp) + 1;
606 p = wl_array_add(&opts, len);
607 if (p) strncpy(p, tmp, len);
609 p = wl_array_add(&opts, 9);
610 if (p) strncpy(p, "opt_none", 9);
612 rs->req_curr_buff.set = EINA_FALSE;
613 add_opts = EINA_TRUE;
616 RSMDBG("CHANGED_BUFF send:%d type:%u tbm:%p fd:%d(%d) add_opts:%d EV_FILTER(%d):%u",
617 NULL, NULL, "SURFACE", rs,
618 send, buff_type, tbm, img_file_fd, img_file_size, add_opts,
619 rs->changed_buff_ev_filter.use,
620 rs->changed_buff_ev_filter.filter);
622 tizen_remote_surface_send_changed_buffer(rs->resource,
627 ecore_time_get() * 1000,
628 add_opts ? &opts : NULL);
631 tizen_remote_surface_send_update_buffer(rs->resource,
633 ecore_time_get() * 1000);
637 wl_array_release(&opts);
643 _remote_surface_buff_send(E_Comp_Wl_Remote_Surface *rs)
645 enum tizen_remote_surface_buffer_type buff_type;
646 E_Comp_Wl_Remote_Provider *provider;
647 E_Comp_Wl_Remote_Source *source;
648 E_Comp_Wl_Buffer *buff = NULL;
650 int fd = _rsm->dummy_fd;
652 Eina_Bool res = EINA_FALSE;
654 E_Client *src_ec = NULL;
657 provider = rs->provider;
661 src_ec = provider->common.ec;
666 src_ec = source->common.ec;
667 img_path = (char *)source->image_path;
670 EINA_SAFETY_ON_NULL_RETURN_VAL(src_ec, EINA_FALSE);
672 buff = e_pixmap_resource_get(src_ec->pixmap);
675 buff_type = TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM;
678 /* TODO: if client wants to receive image file for the remote_surfac_provider,
679 * then makes image file from tbm buffer and sends information for that file.
680 * otherwise, just sends tbm buffer to the client.
682 res = _remote_surface_changed_buff_protocol_send(rs,
685 (unsigned int)img_size,
691 EINA_SAFETY_ON_NULL_RETURN_VAL(img_path, EINA_FALSE);
693 fd = open(img_path, O_RDONLY);
694 EINA_SAFETY_ON_FALSE_RETURN_VAL(fd != -1, EINA_FALSE);
696 img_size = lseek(fd, 0, SEEK_END);
697 EINA_SAFETY_ON_FALSE_GOTO(img_size > 0, close_fd);
699 buff_type = TIZEN_REMOTE_SURFACE_BUFFER_TYPE_IMAGE_FILE;
702 /* TODO: if client wants to receive image file for the remote_surfac_provider,
703 * then makes image file from tbm buffer and sends information for that file.
704 * otherwise, just sends tbm buffer to the client.
706 res = _remote_surface_changed_buff_protocol_send(rs,
709 (unsigned int)img_size,
724 _remote_surface_visible_set(E_Comp_Wl_Remote_Surface *remote_surface, Eina_Bool set)
726 E_Comp_Wl_Remote_Provider *provider;
728 if (remote_surface->visible == set) return;
730 remote_surface->visible = set;
732 RSMDBG("Switch visible:%d",
734 "SURFACE", remote_surface, remote_surface->visible);
736 provider = remote_surface->provider;
737 if (!provider) return;
739 _remote_provider_visible_set(provider, set);
743 _remote_surface_bind_client_set(E_Comp_Wl_Remote_Surface *remote_surface, E_Client *ec)
745 if (!remote_surface) return;
747 RSMINF("Set bind_ec:%p, bind_ref:%d",
749 "SURFACE", remote_surface, ec, ec->remote_surface.bind_ref + 1);
751 remote_surface->bind_ec = ec;
752 remote_surface->bind_ec->remote_surface.bind_ref++;
756 _remote_surface_bind_client_unset(E_Comp_Wl_Remote_Surface *remote_surface)
758 if (!remote_surface) return;
760 RSMINF("Unset bind_ec:%p, bind_ref:%d",
762 "SURFACE", remote_surface, remote_surface->bind_ec,
763 remote_surface->bind_ec->remote_surface.bind_ref - 1);
765 remote_surface->bind_ec->remote_surface.bind_ref--;
766 remote_surface->bind_ec = NULL;
770 _remote_surface_bind_client(E_Comp_Wl_Remote_Surface *remote_surface, E_Client *ec)
772 if (!remote_surface) return;
773 if ((ec) && (remote_surface->bind_ec == ec)) return;
775 /* clear previous binding */
776 if (remote_surface->bind_ec)
778 RSMINF("Clear previous bind_ec:%p",
780 "SURFACE", remote_surface, remote_surface->bind_ec);
782 remote_surface->bind_ec->comp_data->pending.sx = 0;
783 remote_surface->bind_ec->comp_data->pending.sy = 0;
784 remote_surface->bind_ec->comp_data->pending.new_attach = EINA_TRUE;
786 #if 0 /* FIXME: no proper position to add below codes */
787 /* when unbinded, ignore_output_transform event is sended. And map should be disable. */
788 remote_surface->bind_ec->comp_data->pending.buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
789 remote_surface->bind_ec->comp_data->pending.buffer_viewport.changed = 0;
790 remote_surface->bind_ec->comp_data->scaler.buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
791 remote_surface->bind_ec->comp_data->scaler.buffer_viewport.changed = 0;
792 e_comp_wl_map_apply(remote_surface->bind_ec);
795 e_comp_wl_surface_attach(remote_surface->bind_ec, NULL);
796 e_comp_object_render_update_del(remote_surface->bind_ec->frame);
798 eina_hash_del(_rsm->bind_surface_hash, &remote_surface->bind_ec, remote_surface);
799 _remote_surface_bind_client_unset(remote_surface);
801 /* try to send latest buffer of the provider to the consumer when unbinding
802 * the remote surface to avoid showing old buffer on consumer's window for a while.
804 if (remote_surface->provider)
806 E_Comp_Wl_Buffer *buffer;
808 RSMINF("Try to send latest buffer of provider:%p(ec:%p)",
810 "SURFACE", remote_surface,
811 remote_surface->provider,
812 remote_surface->provider->common.ec);
814 EINA_SAFETY_ON_NULL_GOTO(remote_surface->provider->common.ec, bind_ec_set);
816 buffer = e_pixmap_resource_get(remote_surface->provider->common.ec->pixmap);
817 EINA_SAFETY_ON_NULL_GOTO(buffer, bind_ec_set);
819 _remote_surface_changed_buff_protocol_send(remote_surface,
820 TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM,
831 if (e_object_is_del(E_OBJECT(ec)))
833 ERR("Trying to bind with deleted EC(%p)", ec);
837 /* TODO: enable user geometry? */
838 e_policy_allow_user_geometry_set(ec, EINA_TRUE);
839 _remote_surface_bind_client_set(remote_surface, ec);
840 eina_hash_add(_rsm->bind_surface_hash, &remote_surface->bind_ec, remote_surface);
842 /* try to set latest buffer of the provider to bind_ec */
843 if (remote_surface->provider && remote_surface->provider->common.ec)
845 E_Comp_Wl_Buffer *buffer;
847 buffer = e_pixmap_resource_get(remote_surface->provider->common.ec->pixmap);
848 EINA_SAFETY_ON_NULL_RETURN(buffer);
850 _e_comp_wl_remote_surface_state_buffer_set(&remote_surface->bind_ec->comp_data->pending, buffer);
852 remote_surface->bind_ec->comp_data->pending.sx = 0;
853 remote_surface->bind_ec->comp_data->pending.sy = 0;
854 remote_surface->bind_ec->comp_data->pending.new_attach = EINA_TRUE;
856 remote_surface->bind_ec->comp_data->pending.buffer_viewport =
857 remote_surface->provider->common.ec->comp_data->scaler.buffer_viewport;
859 e_comp_wl_surface_commit(remote_surface->bind_ec);
865 _remote_surface_ignore_output_transform_send(E_Comp_Wl_Remote_Common *common)
867 E_Comp_Wl_Remote_Surface *remote_surface;
870 EINA_SAFETY_ON_NULL_RETURN(common);
872 if (eina_list_count(common->surfaces) != 1)
874 msg = "remote surface count = 0 or over 1";
878 remote_surface = eina_list_nth(common->surfaces, 0);
879 if (remote_surface && remote_surface->bind_ec)
881 msg = "1 binding remote surface";
885 if (common->is_offscreen)
892 msg = "not offscreen";
897 if (common->ignore_output_transform != EINA_TRUE)
899 ELOGF("TRANSFORM", "ignore output transform: %s", common->ec, msg);
900 e_comp_screen_rotation_ignore_output_transform_send(common->ec, EINA_TRUE);
901 common->ignore_output_transform = EINA_TRUE;
906 if (common->ignore_output_transform != EINA_FALSE)
908 ELOGF("TRANSFORM", "not ignore output transform: %s", common->ec, msg);
909 e_comp_screen_rotation_ignore_output_transform_send(common->ec, EINA_FALSE);
910 common->ignore_output_transform = EINA_FALSE;
916 _remote_source_send_image_update(E_Comp_Wl_Remote_Source *source)
921 E_Comp_Wl_Remote_Surface *remote_surface;
923 if (!source->image_path) return;
925 fd = open(source->image_path, O_RDONLY);
932 image_size = lseek(fd, 0, SEEK_END);
939 RSMDBG("send image fd(%d) path(%s) size(%jd)",
940 NULL, source->common.ec, "SOURCE", source, fd, source->image_path, (intmax_t)image_size);
942 EINA_LIST_FOREACH(source->common.surfaces, l, remote_surface)
944 if (remote_surface->version < TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION)
947 _remote_surface_changed_buff_protocol_send(remote_surface,
948 TIZEN_REMOTE_SURFACE_BUFFER_TYPE_IMAGE_FILE,
950 (unsigned int)image_size,
960 void *shm_buffer_ptr;
961 int shm_buffer_stride;
963 unsigned int shm_buffer_format;
964 struct wl_shm_pool *shm_pool;
966 tbm_surface_h tbm_surface;
976 void *shm_buffer_ptr;
977 int shm_buffer_stride;
979 unsigned int shm_buffer_format;
980 struct wl_shm_pool *shm_pool;
982 tbm_surface_h tbm_surface;
986 const char *image_path;
989 Capture_Data *child_data;
992 static E_Comp_Wl_Remote_Source *
993 _remote_source_find(E_Client *ec)
995 E_Comp_Wl_Remote_Source *source;
997 EINA_SAFETY_ON_NULL_RETURN_VAL(_rsm, NULL);
998 EINA_SAFETY_ON_NULL_RETURN_VAL(_rsm->source_hash, NULL);
1000 source = eina_hash_find(_rsm->source_hash, &ec);
1004 static E_Comp_Wl_Remote_Source *
1005 _remote_source_get(E_Client *ec)
1007 E_Comp_Wl_Remote_Source *source = NULL;
1009 source = _remote_source_find(ec);
1012 if (e_object_is_del(E_OBJECT(ec)))
1015 source = E_NEW(E_Comp_Wl_Remote_Source, 1);
1016 if (!source) return NULL;
1018 source->common.ec = ec;
1019 eina_hash_add(_rsm->source_hash, &ec, source);
1026 _remote_source_destroy(E_Comp_Wl_Remote_Source *source)
1028 E_Comp_Wl_Remote_Surface *remote_surface;
1029 if (!source) return;
1031 RSMDBG("remote source destroy", NULL, source->common.ec,"SOURCE", source);
1035 RSMDBG("IMG save is cancelled. th:%p pending destroy",
1036 source->common.ec->pixmap, source->common.ec, "SOURCE",
1037 source, source->th);
1038 ecore_thread_cancel(source->th);
1039 source->deleted = EINA_TRUE;
1043 if (source->ref_as_child > 0)
1045 RSMDBG("Parent IMG save is running. ref_as_child:%d pending destroy",
1046 source->common.ec->pixmap, source->common.ec, "SOURCE",
1047 source, source->ref_as_child);
1048 source->deleted = EINA_TRUE;
1053 eina_hash_del_by_data(_rsm->source_hash, source);
1055 EINA_LIST_FREE(source->common.surfaces, remote_surface)
1057 if (remote_surface->source == source)
1059 remote_surface->source = NULL;
1060 tizen_remote_surface_send_missing(remote_surface->resource);
1064 /* is it ok without client's ack ?*/
1065 if (source->image_path)
1067 if (!e_config->hold_prev_win_img)
1069 RSMDBG("IMG del %s", NULL, source->common.ec, "SOURCE", source, source->image_path);
1070 ecore_file_remove(source->image_path);
1072 eina_stringshare_del(source->image_path);
1078 static pixman_format_code_t
1079 _remote_source_image_data_pixman_format_get_from_tbm_surface(tbm_format format)
1083 case TBM_FORMAT_ARGB8888: return PIXMAN_a8r8g8b8;
1084 case TBM_FORMAT_XRGB8888: return PIXMAN_x8r8g8b8;
1085 default: return PIXMAN_x8r8g8b8;
1089 static pixman_format_code_t
1090 _remote_source_image_data_pixman_format_get_from_shm_buffer(uint32_t format)
1094 case WL_SHM_FORMAT_ARGB8888: return PIXMAN_a8r8g8b8;
1095 case WL_SHM_FORMAT_XRGB8888: return PIXMAN_x8r8g8b8;
1096 default: return PIXMAN_x8r8g8b8;
1100 static tbm_surface_h
1101 _remote_source_image_data_transform(Thread_Data *td, int w, int h)
1104 tbm_surface_h transform_surface = NULL;
1105 tbm_surface_info_s info;
1107 pixman_image_t *src_img = NULL, *dst_img = NULL;
1108 pixman_format_code_t src_format, dst_format;
1109 pixman_transform_t t;
1110 struct pixman_f_transform ft;
1111 unsigned char *src_ptr = NULL, *dst_ptr = NULL;
1112 int c = 0, s = 0, tx = 0, ty = 0;
1115 tbm_surface_h c_transform_surface = NULL;
1116 tbm_surface_info_s c_info;
1117 pixman_image_t *c_src_img = NULL, *c_dst_img = NULL;
1118 pixman_format_code_t c_src_format, c_dst_format;
1119 pixman_transform_t c_t;
1120 struct pixman_f_transform c_ft;
1121 unsigned char *c_src_ptr = NULL, *c_dst_ptr = NULL;
1122 int c_x, c_y, c_w, c_h;
1123 int c_tx, c_ty, c_tw, c_th;
1125 EINA_SAFETY_ON_NULL_RETURN_VAL(td, NULL);
1127 if (td->transform > WL_OUTPUT_TRANSFORM_270) return NULL;
1129 if (td->tbm_surface)
1131 src_format = _remote_source_image_data_pixman_format_get_from_tbm_surface(tbm_surface_get_format(td->tbm_surface));
1132 dst_format = src_format;
1134 tbm_surface_map(td->tbm_surface, TBM_SURF_OPTION_READ, &info);
1135 src_ptr = info.planes[0].ptr;
1137 src_img = pixman_image_create_bits(src_format, w, h, (uint32_t*)src_ptr, info.planes[0].stride);
1138 EINA_SAFETY_ON_NULL_GOTO(src_img, clean_up);
1140 else if (td->shm_buffer_ptr)
1142 src_format = _remote_source_image_data_pixman_format_get_from_shm_buffer(td->shm_buffer_format);
1143 dst_format = src_format;
1145 src_ptr = td->shm_buffer_ptr;
1146 src_img = pixman_image_create_bits(src_format, w, h, (uint32_t*)src_ptr, w * 4);
1147 EINA_SAFETY_ON_NULL_GOTO(src_img, clean_up);
1151 ERR("invalid source buffer");
1155 if (td->transform == WL_OUTPUT_TRANSFORM_90)
1157 c = 0, s = -1, tx = -h;
1160 else if (td->transform == WL_OUTPUT_TRANSFORM_180)
1162 c = -1, s = 0, tx = -w, ty = -h;
1165 else if (td->transform == WL_OUTPUT_TRANSFORM_270)
1167 c = 0, s = 1, ty = -w;
1176 transform_surface = tbm_surface_create(tw, th, tbm_surface_get_format(td->tbm_surface));
1177 EINA_SAFETY_ON_NULL_GOTO(transform_surface, clean_up);
1179 tbm_surface_map(transform_surface, TBM_SURF_OPTION_WRITE, &info);
1180 dst_ptr = info.planes[0].ptr;
1182 dst_img = pixman_image_create_bits(dst_format, tw, th, (uint32_t*)dst_ptr, info.planes[0].stride);
1183 EINA_SAFETY_ON_NULL_GOTO(dst_img, clean_up);
1185 pixman_f_transform_init_identity(&ft);
1186 pixman_f_transform_translate(&ft, NULL, tx, ty);
1187 pixman_f_transform_rotate(&ft, NULL, c, s);
1189 pixman_transform_from_pixman_f_transform(&t, &ft);
1190 pixman_image_set_transform(src_img, &t);
1192 pixman_image_composite(PIXMAN_OP_SRC, src_img, NULL, dst_img, 0, 0, 0, 0, 0, 0, tw, th);
1197 c_x = td->child_data->x;
1198 c_y = td->child_data->y;
1199 c_w = td->child_data->w;
1200 c_h = td->child_data->h;
1207 if (td->child_data->tbm_surface)
1209 c_src_format = _remote_source_image_data_pixman_format_get_from_tbm_surface(tbm_surface_get_format(td->child_data->tbm_surface));
1210 c_dst_format = c_src_format;
1212 tbm_surface_map(td->child_data->tbm_surface, TBM_SURF_OPTION_READ, &c_info);
1213 c_src_ptr = c_info.planes[0].ptr;
1215 c_src_img = pixman_image_create_bits(c_src_format, c_w, c_h, (uint32_t*)c_src_ptr, c_info.planes[0].stride);
1216 EINA_SAFETY_ON_NULL_GOTO(c_src_img, clean_up);
1218 else if (td->child_data->shm_buffer_ptr)
1220 c_src_format = _remote_source_image_data_pixman_format_get_from_shm_buffer(td->child_data->shm_buffer_format);
1221 c_dst_format = c_src_format;
1223 c_src_ptr = td->child_data->shm_buffer_ptr;
1224 c_src_img = pixman_image_create_bits(c_src_format, c_w, c_h, (uint32_t*)c_src_ptr, c_w * 4);
1225 EINA_SAFETY_ON_NULL_GOTO(c_src_img, clean_up);
1229 ERR("invalid source buffer");
1233 if (td->child_data->transform == WL_OUTPUT_TRANSFORM_90)
1235 c = 0, s = -1, c_tx = -c_h;
1236 c_tw = c_h, c_th = c_w;
1238 else if (td->child_data->transform == WL_OUTPUT_TRANSFORM_180)
1240 c = -1, s = 0, c_tx = -c_w, c_ty = -c_h;
1241 c_tw = c_w, c_th = c_h;
1243 else if (td->child_data->transform == WL_OUTPUT_TRANSFORM_270)
1245 c = 0, s = 1, c_ty = -c_w;
1246 c_tw = c_h, c_th = c_w;
1251 c_tw = c_w, c_th = c_h;
1254 c_transform_surface = tbm_surface_create(c_tw, c_th, tbm_surface_get_format(td->child_data->tbm_surface));
1255 EINA_SAFETY_ON_NULL_GOTO(c_transform_surface, clean_up);
1257 tbm_surface_map(c_transform_surface, TBM_SURF_OPTION_WRITE, &c_info);
1258 c_dst_ptr = c_info.planes[0].ptr;
1260 c_dst_img = pixman_image_create_bits(c_dst_format, c_tw, c_th, (uint32_t*)c_dst_ptr, c_info.planes[0].stride);
1261 EINA_SAFETY_ON_NULL_GOTO(c_dst_img, clean_up);
1263 pixman_f_transform_init_identity(&c_ft);
1264 pixman_f_transform_translate(&c_ft, NULL, c_tx, c_ty);
1265 pixman_f_transform_rotate(&c_ft, NULL, c, s);
1267 pixman_transform_from_pixman_f_transform(&c_t, &c_ft);
1268 pixman_image_set_transform(c_src_img, &c_t);
1270 pixman_image_composite(PIXMAN_OP_SRC, c_src_img, NULL, c_dst_img, 0, 0, 0, 0, 0, 0, c_tw, c_th);
1272 RSMDBG("image composite with child. child(win:%zx, ec:%p)",
1273 td->ec->pixmap, td->ec, "SOURCE", NULL,
1274 e_client_util_win_get(td->child_data->ec), td->child_data->ec);
1276 pixman_image_composite(PIXMAN_OP_OVER, c_dst_img, NULL, dst_img, 0, 0, 0, 0, c_x, c_y, tw, th);
1282 if (c_src_ptr && td->child_data->tbm_surface) tbm_surface_unmap(td->child_data->tbm_surface);
1283 if (c_dst_ptr) tbm_surface_unmap(c_transform_surface);
1285 if (c_transform_surface)
1287 tbm_surface_destroy(c_transform_surface);
1288 c_transform_surface = NULL;
1291 if (c_src_img) pixman_image_unref(c_src_img);
1292 if (c_dst_img) pixman_image_unref(c_dst_img);
1295 if (src_ptr && td->tbm_surface) tbm_surface_unmap(td->tbm_surface);
1296 if (dst_ptr) tbm_surface_unmap(transform_surface);
1298 // if dst_img is null, then trasform is failed. So we should destroy transform_surface.
1301 tbm_surface_destroy(transform_surface);
1302 transform_surface = NULL;
1305 if (src_img) pixman_image_unref(src_img);
1306 if (dst_img) pixman_image_unref(dst_img);
1308 return transform_surface;
1312 _remote_source_image_data_save(Thread_Data *td, const char *path, const char *name)
1314 void *shm_buffer_ptr = NULL;
1315 tbm_surface_h tbm_surface = NULL, transform_surface = NULL;
1318 char dest[2048], fname[2048];
1319 const char *dupname;
1320 int id = 0, ret = 0;
1322 EINA_SAFETY_ON_NULL_RETURN_VAL(td, NULL);
1323 EINA_SAFETY_ON_NULL_RETURN_VAL(path, NULL);
1324 EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
1326 snprintf(fname, sizeof(fname), "%s-%d", name, id);
1327 snprintf(dest, sizeof(dest), "%s/%s.png", path, fname);
1328 while (ecore_file_exists(dest))
1330 snprintf(fname, sizeof(fname), "%s-%d", name, ++id);
1331 snprintf(dest, sizeof(dest), "%s/%s.png", path, fname);
1334 shm_buffer_ptr = td->shm_buffer_ptr;
1335 tbm_surface = td->tbm_surface;
1339 stride = td->shm_buffer_stride;
1341 h = td->shm_buffer_h;
1343 transform_surface = _remote_source_image_data_transform(td, w, h);
1344 if (transform_surface)
1346 tbm_surface_info_s info;
1347 tbm_surface_map(transform_surface, TBM_SURF_OPTION_READ|TBM_SURF_OPTION_WRITE, &info);
1348 ptr = info.planes[0].ptr;
1352 ptr = shm_buffer_ptr;
1353 EINA_SAFETY_ON_NULL_RETURN_VAL(ptr, NULL);
1356 dupname = strdup(fname);
1357 ret = tbm_surface_internal_capture_shm_buffer(ptr, w, h, stride, path, dupname, "png");
1359 if (transform_surface)
1361 tbm_surface_unmap(transform_surface);
1362 tbm_surface_destroy(transform_surface);
1365 free((void*)dupname);
1369 else if (tbm_surface)
1371 w = tbm_surface_get_width(tbm_surface);
1372 EINA_SAFETY_ON_FALSE_RETURN_VAL(w > 0, NULL);
1373 h = tbm_surface_get_height(tbm_surface);
1374 EINA_SAFETY_ON_FALSE_RETURN_VAL(h > 0, NULL);
1376 transform_surface = _remote_source_image_data_transform(td, w, h);
1377 if (transform_surface)
1378 tbm_surface = transform_surface;
1380 RSMDBG("image save. transform_surface=%p transform=%d", td->ec->pixmap, td->ec, "SOURCE", NULL, transform_surface, td->transform);
1382 dupname = strdup(fname);
1383 ret = tbm_surface_internal_capture_buffer(tbm_surface, path, dupname, "png");
1385 if (transform_surface)
1386 tbm_surface_destroy(transform_surface);
1388 free((void*)dupname);
1397 return strdup(dest);
1401 _remote_source_child_data_release(Thread_Data *td)
1403 E_Comp_Wl_Remote_Source *source;
1407 if (!td->child_data) return;
1409 if (td->child_data->tbm_surface)
1410 tbm_surface_internal_unref(td->child_data->tbm_surface);
1412 if (td->child_data->shm_pool)
1413 wl_shm_pool_unref(td->child_data->shm_pool);
1415 ec = td->child_data->ec;
1418 source = _remote_source_find(ec);
1419 if (!source) return;
1421 e_comp_wl_buffer_reference(&source->buffer_ref, NULL);
1422 source->ref_as_child--;
1423 RSMDBG("Child data release. ref_as_child:%d", NULL, ec, "SOURCE", source, source->ref_as_child);
1425 if ((source->deleted) || (e_object_is_del(E_OBJECT(ec))))
1427 _remote_source_destroy(source);
1430 e_object_unref(E_OBJECT(ec));
1432 E_FREE(td->child_data);
1436 _remote_source_child_data_create(Thread_Data *td, E_Client *ec)
1438 Capture_Data *capture_data;
1439 E_Comp_Wl_Remote_Source *source;
1440 E_Comp_Wl_Buffer *buffer = NULL;
1441 struct wl_shm_buffer *shm_buffer;
1442 struct wl_shm_pool *shm_pool;
1443 void *shm_buffer_ptr = NULL;
1444 int shm_buffer_stride, shm_buffer_h;
1445 tbm_surface_h tbm_surface;
1447 if (!td) return EINA_FALSE;
1448 if (!ec) return EINA_FALSE;
1450 source = _remote_source_get(ec);
1451 if (!source) return EINA_FALSE;
1453 if (!(buffer = e_pixmap_resource_get(ec->pixmap))) return EINA_FALSE;
1457 // how do we handle this case?
1458 _remote_source_child_data_release(td);
1461 capture_data = E_NEW(Capture_Data, 1);
1462 if (!capture_data) return EINA_FALSE;
1464 e_object_ref(E_OBJECT(ec));
1465 capture_data->ec = ec;
1467 capture_data->x = ec->x;
1468 capture_data->y = ec->y;
1469 capture_data->w = ec->w;
1470 capture_data->h = ec->h;
1472 capture_data->transform = e_comp_wl_output_buffer_transform_get(ec);
1474 e_comp_wl_buffer_reference(&source->buffer_ref, buffer);
1475 switch (buffer->type)
1477 case E_COMP_WL_BUFFER_TYPE_SHM:
1478 shm_buffer = wl_shm_buffer_get(buffer->resource);
1479 if (!shm_buffer) goto end;
1481 shm_buffer_ptr = wl_shm_buffer_get_data(shm_buffer);
1482 if (!shm_buffer_ptr) goto end;
1484 shm_buffer_stride = wl_shm_buffer_get_stride(shm_buffer);
1485 if (shm_buffer_stride <= 0) goto end;
1487 shm_buffer_h = wl_shm_buffer_get_height(shm_buffer);
1488 if (shm_buffer_h <= 0) goto end;
1490 shm_pool = wl_shm_buffer_ref_pool(shm_buffer);
1491 if (!shm_pool) goto end;
1493 capture_data->shm_buffer_format = wl_shm_buffer_get_format(shm_buffer);
1494 capture_data->shm_buffer_ptr = shm_buffer_ptr;
1495 capture_data->shm_buffer_stride = shm_buffer_stride;
1496 capture_data->shm_buffer_h = shm_buffer_h;
1497 capture_data->shm_pool = shm_pool;
1500 case E_COMP_WL_BUFFER_TYPE_NATIVE:
1501 case E_COMP_WL_BUFFER_TYPE_VIDEO:
1502 tbm_surface = wayland_tbm_server_get_surface(e_comp_wl->tbm.server, buffer->resource);
1503 if (!tbm_surface) goto end;
1505 tbm_surface_internal_ref(tbm_surface);
1506 capture_data->tbm_surface = tbm_surface;
1509 case E_COMP_WL_BUFFER_TYPE_TBM:
1510 tbm_surface = buffer->tbm_surface;
1511 if (!tbm_surface) goto end;
1513 tbm_surface_internal_ref(tbm_surface);
1514 capture_data->tbm_surface = tbm_surface;
1521 td->child_data = capture_data;
1522 source->ref_as_child++;
1523 RSMDBG("Child data create. ref_as_child:%d", NULL, ec, "SOURCE", source, source->ref_as_child);
1527 e_comp_wl_buffer_reference(&source->buffer_ref, NULL);
1528 e_object_unref(E_OBJECT(ec));
1529 E_FREE(capture_data);
1535 _remote_source_child_is_placed_above(E_Client *child, E_Client *ec)
1537 E_Client *above = NULL;
1539 for (above = e_client_above_get(ec); above; above = e_client_above_get(above))
1549 _remote_source_child_data_check(Thread_Data *td)
1551 Eina_List *list, *l;
1552 E_Client *ec = NULL;
1553 E_Client *child_ec = NULL;
1556 if (!ec) return EINA_FALSE;
1558 list = eina_list_clone(ec->transients);
1560 EINA_LIST_FOREACH(list, l, child_ec)
1562 if (!child_ec->comp_data) continue;
1563 if (!child_ec->comp_data->mapped) continue;
1565 if (child_ec->iconic && child_ec->exp_iconify.by_client)
1568 if (child_ec->bg_state)
1571 if (!e_policy_client_is_keyboard(child_ec))
1574 if (!_remote_source_child_is_placed_above(child_ec, ec))
1577 _remote_source_child_data_create(td, child_ec);
1581 eina_list_free(list);
1587 _remote_source_save(void *data, Ecore_Thread *th)
1592 char dest_dir[1024];
1593 const char *dest_path, *dupname, *dupdir;
1596 if (!(td = data)) return;
1600 if (ecore_thread_check(th)) return;
1602 run_dir = e_util_env_get("XDG_RUNTIME_DIR");
1603 if (!run_dir) return;
1605 snprintf(dest_dir, sizeof(dest_dir), "%s/.e-img", run_dir);
1608 if (!ecore_file_exists(dest_dir))
1609 ecore_file_mkdir(dest_dir);
1610 dupdir = strdup(dest_dir);
1612 snprintf(name, sizeof(name),
1615 e_pixmap_res_id_get(ec->pixmap));
1617 dupname = strdup(name);
1619 dest_path = _remote_source_image_data_save(td, dupdir, dupname);
1622 RSMDBG("IMG save success. th:%p file:%s", NULL, ec, "SOURCE", NULL, th, dest_path);
1623 td->image_path = eina_stringshare_add(dest_path);
1624 free((void*)dest_path);
1628 RSMDBG("IMG save failure. th:%p file:%s", NULL, ec, "SOURCE", NULL, th, dest_path);
1630 free((void*)dupname);
1631 free((void*)dupdir);
1635 _remote_source_save_done(void *data, Ecore_Thread *th)
1637 Thread_Data *td = data;
1639 E_Comp_Wl_Remote_Source *source = NULL;
1646 source = _remote_source_find(ec);
1647 if (!source) goto end;
1649 RSMDBG("IMG save DONE. th:%p", NULL, ec, "SOURCE", source, th);
1651 if (th == source->th)
1654 e_comp_wl_buffer_reference(&source->buffer_ref, NULL);
1656 if ((source->deleted) || (e_object_is_del(E_OBJECT(ec))))
1658 _remote_source_destroy(source);
1662 if (!td->image_path) goto end;
1664 RSMDBG("Source save DONE path(%s)", source->common.ec->pixmap, source->common.ec,
1665 "SOURCE", source, td->image_path);
1667 /* remove previous file */
1668 if ((source->image_path) && (e_util_strcmp(source->image_path, td->image_path)))
1670 if (!e_config->hold_prev_win_img)
1672 RSMDBG("IMG del %s", ec->pixmap, ec, "SOURCE", source, source->image_path);
1673 ecore_file_remove(source->image_path);
1675 eina_stringshare_del(source->image_path);
1677 source->image_path = eina_stringshare_add(td->image_path);
1678 _remote_source_send_image_update(source);
1680 ec->saved_img = EINA_TRUE;
1684 RSMDBG("IMG not matched. del. src:%s td:%s", ec->pixmap, ec, "SOURCE",
1685 source, source->image_path, td->image_path);
1686 ecore_file_remove(td->image_path);
1691 _remote_source_child_data_release(td);
1695 e_object_unref(E_OBJECT(ec));
1696 if (td->tbm_surface)
1697 tbm_surface_internal_unref(td->tbm_surface);
1699 wl_shm_pool_unref(td->shm_pool);
1701 eina_stringshare_del(td->image_path);
1706 _remote_source_save_cancel(void *data, Ecore_Thread *th)
1708 Thread_Data *td = data;
1710 E_Comp_Wl_Remote_Source *source = NULL;
1711 Eina_Bool del = EINA_FALSE;
1718 source = _remote_source_find(ec);
1719 if (!source) goto end;
1721 RSMDBG("IMG save CANCELED. th:%p %s", source->common.ec->pixmap, source->common.ec,
1722 "SOURCE", source, th, td->image_path);
1724 if (th == source->th)
1727 e_comp_wl_buffer_reference(&source->buffer_ref, NULL);
1731 _remote_source_child_data_release(td);
1735 if (!e_config->hold_prev_win_img)
1739 RSMDBG("IMG del %s", NULL, source->common.ec, "SOURCE", source, td->image_path);
1740 ecore_file_remove(td->image_path);
1744 if (source->deleted)
1746 _remote_source_destroy(source);
1751 e_object_unref(E_OBJECT(ec));
1752 if (td->tbm_surface)
1753 tbm_surface_internal_unref(td->tbm_surface);
1755 wl_shm_pool_unref(td->shm_pool);
1757 eina_stringshare_del(td->image_path);
1760 if ((!del) && (source))
1762 if (source->defer_img_save)
1764 RSMDBG("IMG save retry", NULL, source->common.ec, "SOURCE", source);
1765 _remote_source_save_start(source);
1766 source->defer_img_save = EINA_FALSE;
1771 /* Stop capture job when the window is uniconified while capturing
1772 * on another thread.
1774 * If a commit event occurs for iconified window, then does cancellation
1775 * for capture thread and set the defer_img_save to true to restart the
1776 * capture thread again for new window buffer.
1778 * It can be using ecore_thread_check API to check whether the capture
1782 _remote_source_save_start(E_Comp_Wl_Remote_Source *source)
1785 E_Comp_Wl_Buffer *buffer = NULL;
1787 struct wl_shm_buffer *shm_buffer;
1788 struct wl_shm_pool *shm_pool;
1789 void *shm_buffer_ptr = NULL;
1790 int shm_buffer_stride, shm_buffer_h;
1791 tbm_surface_h tbm_surface;
1793 if (!(ec = source->common.ec)) return;
1794 if (!(buffer = e_pixmap_resource_get(ec->pixmap))) return;
1795 if (!e_config->save_win_buffer) return;
1799 RSMDBG("ALREADY doing capture", NULL, source->common.ec, "SOURCE", source);
1803 td = E_NEW(Thread_Data, 1);
1806 e_object_ref(E_OBJECT(ec));
1809 td->transform = e_comp_wl_output_buffer_transform_get(ec);
1811 e_comp_wl_buffer_reference(&source->buffer_ref, buffer);
1812 switch (buffer->type)
1814 case E_COMP_WL_BUFFER_TYPE_SHM:
1815 shm_buffer = wl_shm_buffer_get(buffer->resource);
1816 if (!shm_buffer) goto end;
1818 shm_buffer_ptr = wl_shm_buffer_get_data(shm_buffer);
1819 if (!shm_buffer_ptr) goto end;
1821 shm_buffer_stride = wl_shm_buffer_get_stride(shm_buffer);
1822 if (shm_buffer_stride <= 0) goto end;
1824 shm_buffer_h = wl_shm_buffer_get_height(shm_buffer);
1825 if (shm_buffer_h <= 0) goto end;
1827 shm_pool = wl_shm_buffer_ref_pool(shm_buffer);
1828 if (!shm_pool) goto end;
1830 td->shm_buffer_format = wl_shm_buffer_get_format(shm_buffer);
1831 td->shm_buffer_ptr = shm_buffer_ptr;
1832 td->shm_buffer_stride = shm_buffer_stride;
1833 td->shm_buffer_h = shm_buffer_h;
1834 td->shm_pool = shm_pool;
1836 case E_COMP_WL_BUFFER_TYPE_NATIVE:
1837 case E_COMP_WL_BUFFER_TYPE_VIDEO:
1838 tbm_surface = wayland_tbm_server_get_surface(e_comp_wl->tbm.server, buffer->resource);
1839 if (!tbm_surface) goto end;
1841 tbm_surface_internal_ref(tbm_surface);
1842 td->tbm_surface = tbm_surface;
1844 case E_COMP_WL_BUFFER_TYPE_TBM:
1845 tbm_surface = buffer->tbm_surface;
1846 if (!tbm_surface) goto end;
1848 tbm_surface_internal_ref(tbm_surface);
1849 td->tbm_surface = tbm_surface;
1855 _remote_source_child_data_check(td);
1857 source->th = ecore_thread_run(_remote_source_save,
1858 _remote_source_save_done,
1859 _remote_source_save_cancel,
1861 RSMDBG("IMG save START. th:%p", ec->pixmap, ec, "SOURCE", source, source->th);
1864 e_comp_wl_buffer_reference(&source->buffer_ref, NULL);
1865 e_object_unref(E_OBJECT(ec));
1867 _remote_source_child_data_release(td);
1873 _remote_source_save_start_cancel(E_Client *ec)
1875 E_Comp_Wl_Remote_Source *source;
1877 source = _remote_source_find(ec);
1878 if (!source) return;
1879 EINA_SAFETY_ON_FALSE_RETURN(ec == source->common.ec);
1883 RSMDBG("IMG save could be cancelled. UNICONIFY th:%p(cancel:%d) defer_img_save:%d iconic:%d del:%d ec_del:%d",
1884 ec->pixmap, ec, "SOURCE", source,
1885 source->th, ecore_thread_check(source->th),
1886 source->defer_img_save, ec->iconic,
1887 source->deleted, e_object_is_del(E_OBJECT(ec)));
1888 if (!ecore_thread_check(source->th) &&
1890 !e_object_is_del(E_OBJECT(ec)))
1892 RSMDBG("IMG save CANCELLED.", ec->pixmap, ec, "SOURCE", source);
1893 ecore_thread_cancel(source->th);
1899 _remote_source_offscreen_set(E_Comp_Wl_Remote_Source *source, Eina_Bool set)
1901 EINA_SAFETY_ON_NULL_RETURN(source);
1904 source->offscreen_ref++;
1905 RSMDBG("Set offscreen offscreen_ref:%d",
1906 source->common.ec->pixmap, source->common.ec,
1907 "SOURCE", source, source->offscreen_ref);
1909 if (source->offscreen_ref == 1)
1911 _remote_surface_ignore_output_transform_send(&source->common);
1912 source->common.is_offscreen = EINA_TRUE;
1914 source->common.ec->exp_iconify.not_raise = 1;
1915 if (!source->common.ec->exp_iconify.by_client)
1916 e_policy_wl_iconify_state_change_send(source->common.ec, 0);
1918 RSMINF("Un-Set ICONIFY BY Remote_Surface", source->common.ec->pixmap, source->common.ec,
1920 e_client_uniconify(source->common.ec);
1922 source->common.ec->exp_iconify.by_client = 0;
1923 source->common.ec->exp_iconify.skip_by_remote = 1;
1925 EC_CHANGED(source->common.ec);
1930 if (!source->common.is_offscreen)
1933 source->offscreen_ref--;
1934 RSMDBG("Unset offscreen offscreen_ref:%d",
1935 source->common.ec->pixmap, source->common.ec,
1936 "SOURCE", source, source->offscreen_ref);
1938 if (source->offscreen_ref == 0)
1940 _remote_surface_ignore_output_transform_send(&source->common);
1941 source->common.is_offscreen = EINA_FALSE;
1942 source->common.ec->exp_iconify.skip_by_remote = 0;
1943 EC_CHANGED(source->common.ec);
1949 _remote_surface_region_clear(E_Comp_Wl_Remote_Surface *remote_surface)
1952 E_Comp_Wl_Remote_Region *region;
1953 if (!remote_surface) return;
1955 EINA_LIST_FOREACH(remote_surface->regions, l, region)
1957 _remote_region_mirror_clear(region);
1962 _remote_surface_client_set(E_Client *ec, Eina_Bool set)
1965 if ((e_object_is_del(E_OBJECT(ec)))) return;
1967 ec->remote_surface.consumer = set;
1971 _remote_region_cb_mirror_del(void *data, Evas *e, Evas_Object *obj, void *event_info)
1973 E_Comp_Wl_Remote_Region *region = data;
1974 if (!region->mirror) return;
1976 region->mirror = NULL;
1980 _remote_region_cb_resource_destroy(struct wl_resource *resource)
1982 E_Comp_Wl_Remote_Region *region;
1984 region = wl_resource_get_user_data(resource);
1985 if (!region) return;
1987 if (region->remote_surface)
1989 if (region->remote_surface->provider)
1991 _remote_provider_rect_del(region->remote_surface->provider,
1994 region->remote_surface->regions = eina_list_remove(region->remote_surface->regions,
2000 evas_object_event_callback_del_full(region->mirror, EVAS_CALLBACK_DEL, _remote_region_cb_mirror_del, region);
2001 evas_object_del(region->mirror);
2008 _remote_region_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
2010 wl_resource_destroy(resource);
2014 _remote_region_cb_geometry_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t w, int32_t h)
2016 E_Comp_Wl_Remote_Region *region;
2018 region = wl_resource_get_user_data(resource);
2019 if (!region) return;
2021 region->geometry.x = x;
2022 region->geometry.y = y;
2023 region->geometry.w = w;
2024 region->geometry.h = h;
2026 RSMDBG("Region %p geometry set (%d, %d) %dx%d",
2028 "SURFACE", region->remote_surface, region, x, y, w, h);
2031 static const struct tizen_remote_surface_region_interface _remote_region_interface =
2033 _remote_region_cb_destroy,
2034 _remote_region_cb_geometry_set,
2038 _remote_provider_cb_resource_destroy(struct wl_resource *resource)
2040 E_Comp_Wl_Remote_Provider *provider;
2041 E_Comp_Wl_Remote_Surface *remote_surface;
2043 provider = wl_resource_get_user_data(resource);
2044 if (!provider) return;
2047 eina_hash_del(_rsm->provider_hash, &provider->common.ec, provider);
2049 EINA_LIST_FREE(provider->common.surfaces, remote_surface)
2051 if (remote_surface->provider == provider)
2053 /* unset remote buffer from provider */
2054 if (remote_surface->bind_ec)
2055 _remote_surface_bind_client(remote_surface, NULL);
2057 remote_surface->provider = NULL;
2058 //notify of this ejection to remote surface_resource
2059 tizen_remote_surface_send_missing(remote_surface->resource);
2063 _remote_provider_client_set(provider->common.ec, EINA_FALSE);
2068 _remote_provider_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
2070 wl_resource_destroy(resource);
2074 _remote_provider_cb_offscreen_set(struct wl_client *client EINA_UNUSED, struct wl_resource *provider_resource, uint32_t offscreen)
2076 E_Comp_Wl_Remote_Provider *provider;
2078 provider = wl_resource_get_user_data(provider_resource);
2079 if (!provider) return;
2081 if (provider->common.is_offscreen == offscreen) return;
2082 _remote_provider_offscreen_set(provider, offscreen);
2086 _remote_provider_cb_input_event_filter_set(struct wl_client *client EINA_UNUSED, struct wl_resource *provider_resource, uint32_t event_filter)
2088 E_Comp_Wl_Remote_Provider *provider;
2089 E_Comp_Wl_Remote_Surface *remote_surface;
2092 provider = wl_resource_get_user_data(provider_resource);
2093 if (!provider) return;
2095 provider->input_event_filter = event_filter;
2096 RSMDBG("set input event filter 0x%08x",
2097 provider->common.ec->pixmap, provider->common.ec,
2098 "PROVIDER", provider, event_filter);
2100 if (!event_filter) return;
2102 EINA_LIST_FOREACH(provider->common.surfaces, l, remote_surface)
2104 if (remote_surface->version >= TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_SINCE_VERSION)
2105 tizen_remote_surface_send_input_event_filter(remote_surface->resource, event_filter);
2109 static const struct tizen_remote_surface_provider_interface _remote_provider_interface =
2111 _remote_provider_cb_destroy,
2112 _remote_provider_cb_offscreen_set,
2113 _remote_provider_cb_input_event_filter_set,
2117 _remote_surface_cb_tbm_destroy(struct wl_listener *listener, void *data)
2119 E_Comp_Wl_Remote_Surface *remote_surface;
2121 remote_surface = container_of(listener, E_Comp_Wl_Remote_Surface, tbm_destroy_listener);
2122 if (!remote_surface) return;
2124 if (remote_surface->tbm_destroy_listener.notify)
2126 wl_list_remove(&remote_surface->tbm_destroy_listener.link);
2127 remote_surface->tbm_destroy_listener.notify = NULL;
2130 remote_surface->wl_tbm = NULL;
2134 _remote_surface_cb_resource_destroy(struct wl_resource *resource)
2136 E_Comp_Wl_Remote_Surface *remote_surface;
2137 E_Comp_Wl_Remote_Provider *provider;
2138 E_Comp_Wl_Remote_Source *source;
2139 E_Comp_Wl_Remote_Region *region;
2140 E_Comp_Wl_Remote_Buffer *remote_buf;
2142 remote_surface = wl_resource_get_user_data(resource);
2143 if (!remote_surface) return;
2145 provider = remote_surface->provider;
2148 _remote_surface_visible_set(remote_surface, EINA_FALSE);
2149 if (provider->onscreen_parent == remote_surface)
2150 _remote_provider_onscreen_parent_set(provider, NULL);
2152 provider->common.surfaces = eina_list_remove(provider->common.surfaces,
2154 remote_surface->provider = NULL;
2157 source = remote_surface->source;
2160 source->common.surfaces = eina_list_remove(source->common.surfaces, remote_surface);
2161 remote_surface->source = NULL;
2164 EINA_LIST_FREE(remote_surface->regions, region)
2166 region->remote_surface = NULL;
2167 wl_resource_destroy(region->resource);
2170 EINA_LIST_FREE(remote_surface->send_remote_bufs, remote_buf)
2172 remote_buf->remote_surface = NULL;
2173 wayland_tbm_server_send_destroy_buffer(remote_surface->wl_tbm, remote_buf->resource);
2176 if (remote_surface->bind_ec)
2177 _remote_surface_bind_client(remote_surface, NULL);
2178 if (remote_surface->owner)
2180 eina_hash_del_by_key(_rsm->surface_hash, &remote_surface->owner);
2181 _remote_surface_client_set(remote_surface->owner, EINA_FALSE);
2184 if (remote_surface->wl_tbm)
2185 wl_list_remove(&remote_surface->tbm_destroy_listener.link);
2188 _remote_surface_ignore_output_transform_send(&provider->common);
2190 _remote_surface_ignore_output_transform_send(&source->common);
2192 E_FREE(remote_surface);
2196 _remote_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
2198 wl_resource_destroy(resource);
2202 _remote_surface_cb_redirect(struct wl_client *client, struct wl_resource *resource)
2204 E_Comp_Wl_Buffer *buffer;
2205 E_Comp_Wl_Remote_Surface *remote_surface;
2207 EINA_SAFETY_ON_NULL_RETURN(_rsm);
2209 remote_surface = wl_resource_get_user_data(resource);
2210 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2211 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2213 if (remote_surface->provider)
2215 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider->common.ec);
2217 if (remote_surface->redirect)
2219 RSMINF("Already Redirect surface provider:%p(ec:%p)",
2221 "SURFACE", remote_surface,
2222 remote_surface->provider, remote_surface->provider->common.ec);
2227 RSMINF("Redirect surface provider:%p(ec:%p)",
2229 "SURFACE", remote_surface,
2230 remote_surface->provider, remote_surface->provider->common.ec);
2232 remote_surface->redirect = EINA_TRUE;
2234 /* Send input event filter of provider */
2235 if ((remote_surface->provider->input_event_filter) &&
2236 (remote_surface->version >= TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_SINCE_VERSION))
2237 tizen_remote_surface_send_input_event_filter(resource,
2238 remote_surface->provider->input_event_filter);
2240 buffer = e_pixmap_resource_get(remote_surface->provider->common.ec->pixmap);
2241 EINA_SAFETY_ON_NULL_RETURN(buffer);
2243 _remote_surface_changed_buff_protocol_send(remote_surface,
2244 TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM,
2250 else if (remote_surface->source)
2252 EINA_SAFETY_ON_NULL_RETURN(remote_surface->source->common.ec);
2254 if (remote_surface->redirect)
2256 RSMINF("Already Redirect surface source:%p(ec:%p)",
2258 "SURFACE", remote_surface,
2259 remote_surface->source, remote_surface->source->common.ec);
2264 RSMINF("Redirect surface source:%p(ec:%p)",
2266 "SURFACE", remote_surface,
2267 remote_surface->source, remote_surface->source->common.ec);
2269 if (remote_surface->version < TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION)
2272 remote_surface->redirect = EINA_TRUE;
2274 if ((buffer = e_pixmap_resource_get(remote_surface->source->common.ec->pixmap)))
2276 _remote_surface_changed_buff_protocol_send(remote_surface,
2277 TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM,
2285 _remote_source_send_image_update(remote_surface->source);
2291 _remote_surface_cb_unredirect(struct wl_client *client, struct wl_resource *resource)
2293 E_Comp_Wl_Remote_Surface *remote_surface;
2295 remote_surface = wl_resource_get_user_data(resource);
2296 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2297 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2299 remote_surface->redirect = EINA_FALSE;
2300 // _remote_surface_visible_set(remote_surface, EINA_FALSE);
2302 RSMINF("Unredirect surface provider:%p(ec:%p)",
2304 "SURFACE", remote_surface,
2305 remote_surface->provider, remote_surface->provider? remote_surface->provider->common.ec: NULL);
2309 _remote_surface_cb_mouse_event_transfer(struct wl_client *client, struct wl_resource *resource, uint32_t event_type, int32_t device, int32_t button, int32_t x, int32_t y, wl_fixed_t radius_x, wl_fixed_t radius_y, wl_fixed_t pressure, wl_fixed_t angle, uint32_t clas, uint32_t subclas EINA_UNUSED, const char *identifier, uint32_t time)
2311 E_Comp_Wl_Remote_Provider *provider;
2312 E_Comp_Wl_Remote_Surface *remote_surface;
2315 Evas_Device *edev = NULL;
2316 Evas_Device_Class eclas = EVAS_DEVICE_CLASS_NONE;
2317 double eradx, erady, epressure, eangle;
2319 remote_surface = wl_resource_get_user_data(resource);
2320 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2321 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2322 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider);
2323 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider->common.ec);
2325 provider = remote_surface->provider;
2326 ec = provider->common.ec;
2328 if (e_object_is_del(E_OBJECT(ec))) return;
2330 /* identify class */
2331 if (clas == TIZEN_INPUT_DEVICE_CLAS_MOUSE)
2332 eclas = EVAS_DEVICE_CLASS_MOUSE;
2333 else if (clas == TIZEN_INPUT_DEVICE_CLAS_TOUCHSCREEN)
2334 eclas = EVAS_DEVICE_CLASS_TOUCH;
2337 ERR("Not supported device clas(%d) subclas(%d) identifier(%s)",
2338 clas, subclas, identifier);
2341 /* find ecore device*/
2342 edev = _device_get_by_identifier(identifier);
2345 eclas = evas_device_class_get(edev);
2349 eradx = wl_fixed_to_double(radius_x);
2350 erady = wl_fixed_to_double(radius_y);
2351 epressure = wl_fixed_to_double(pressure);
2352 eangle = wl_fixed_to_double(angle);
2354 if (eclas == EVAS_DEVICE_CLASS_MOUSE)
2358 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_DOWN:
2359 e_client_mouse_button_send(ec,
2365 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_UP:
2366 e_client_mouse_button_send(ec,
2372 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_MOVE:
2373 e_client_mouse_move_send(ec,
2378 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_IN:
2379 e_client_mouse_in_send(ec,
2384 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_OUT:
2385 e_client_mouse_out_send(ec,
2390 ERR("Not supported event_type(%d)", event_type);
2394 else if (eclas == EVAS_DEVICE_CLASS_TOUCH)
2398 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_DOWN:
2399 /* FIXME: temporary fix for first touch down w/o move event */
2400 e_client_touch_update_send(ec,
2404 eradx, erady, epressure, eangle,
2406 e_client_touch_send(ec,
2411 eradx, erady, epressure, eangle,
2414 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_UP:
2415 e_client_touch_send(ec,
2420 eradx, erady, epressure, eangle,
2423 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_MOVE:
2424 e_client_touch_update_send(ec,
2428 eradx, erady, epressure, eangle,
2432 ERR("Not supported event_type(%d)", event_type);
2439 _remote_surface_cb_mouse_wheel_transfer(struct wl_client *client, struct wl_resource *resource, uint32_t direction, int32_t z, uint32_t clas, uint32_t subclas, const char *identifier, uint32_t time)
2441 E_Comp_Wl_Remote_Provider *provider;
2442 E_Comp_Wl_Remote_Surface *remote_surface;
2445 Evas_Device *edev = NULL;
2447 remote_surface = wl_resource_get_user_data(resource);
2448 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2449 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2450 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider);
2451 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider->common.ec);
2453 provider = remote_surface->provider;
2454 ec = provider->common.ec;
2456 if (e_object_is_del(E_OBJECT(ec))) return;
2458 /* identify class */
2459 edev = _device_get_by_identifier(identifier);
2461 e_client_mouse_wheel_send(ec, direction, z, edev, time);
2465 _remote_surface_cb_touch_event_transfer(struct wl_client *client, struct wl_resource *resource, uint32_t event_type, int32_t device, int32_t button, int32_t x, int32_t y, wl_fixed_t radius_x, wl_fixed_t radius_y, wl_fixed_t pressure, wl_fixed_t angle, uint32_t clas, uint32_t subclas, const char *identifier, uint32_t time)
2467 E_Comp_Wl_Remote_Provider *provider;
2468 E_Comp_Wl_Remote_Surface *remote_surface;
2471 Evas_Device *edev = NULL;
2472 Evas_Device_Class eclas;
2473 double eradx, erady, epressure, eangle;
2475 remote_surface = wl_resource_get_user_data(resource);
2476 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2477 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2478 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider);
2479 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider->common.ec);
2481 provider = remote_surface->provider;
2482 ec = provider->common.ec;
2484 if (e_object_is_del(E_OBJECT(ec))) return;
2486 /* identify class */
2487 if (clas == TIZEN_INPUT_DEVICE_CLAS_TOUCHSCREEN)
2488 eclas = EVAS_DEVICE_CLASS_TOUCH;
2491 ERR("Not supported device clas(%d) subclas(%d identifier(%s)",
2492 clas, subclas, identifier);
2496 /* find ecore device*/
2497 edev = _device_get_by_identifier(identifier);
2500 eclas = evas_device_class_get(edev);
2504 eradx = wl_fixed_to_double(radius_x);
2505 erady = wl_fixed_to_double(radius_y);
2506 epressure = wl_fixed_to_double(pressure);
2507 eangle = wl_fixed_to_double(angle);
2509 if (eclas == EVAS_DEVICE_CLASS_TOUCH)
2513 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_TOUCH_DOWN:
2514 e_client_touch_update_send(ec,
2518 eradx, erady, epressure, eangle,
2520 e_client_touch_send(ec,
2525 eradx, erady, epressure, eangle,
2528 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_TOUCH_UP:
2529 e_client_touch_send(ec,
2534 eradx, erady, epressure, eangle,
2537 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_TOUCH_MOVE:
2538 e_client_touch_update_send(ec,
2542 eradx, erady, epressure, eangle,
2546 ERR("Not supported event_type(%d)", event_type);
2553 _remote_surface_cb_touch_cancel_transfer(struct wl_client *client, struct wl_resource *resource)
2555 E_Comp_Wl_Remote_Provider *provider;
2556 E_Comp_Wl_Remote_Surface *remote_surface;
2559 remote_surface = wl_resource_get_user_data(resource);
2560 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2561 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2562 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider);
2563 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider->common.ec);
2565 provider = remote_surface->provider;
2566 ec = provider->common.ec;
2568 if (e_object_is_del(E_OBJECT(ec))) return;
2569 e_client_touch_cancel_send(ec);
2573 _remote_surface_cb_key_event_transfer(struct wl_client *client, struct wl_resource *resource, uint32_t event_type, int32_t keycode, uint32_t clas, uint32_t subclas, const char *identifier, uint32_t time)
2575 E_Comp_Wl_Remote_Provider *provider;
2576 E_Comp_Wl_Remote_Surface *remote_surface;
2579 Evas_Device *edev = NULL;
2580 Evas_Device_Class eclas;
2582 remote_surface = wl_resource_get_user_data(resource);
2583 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2584 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2585 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider);
2586 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider->common.ec);
2588 provider = remote_surface->provider;
2589 ec = provider->common.ec;
2591 if (e_object_is_del(E_OBJECT(ec))) return;
2593 /* identify class */
2594 if (clas == TIZEN_INPUT_DEVICE_CLAS_KEYBOARD)
2595 eclas = EVAS_DEVICE_CLASS_KEYBOARD;
2598 ERR("Not supported device class(%d) subclass(%d identifier(%s)",
2599 clas, subclas, identifier);
2603 /* find ecore device*/
2604 edev = _device_get_by_identifier(identifier);
2607 eclas = evas_device_class_get(edev);
2610 if (eclas == EVAS_DEVICE_CLASS_KEYBOARD)
2614 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_KEY_DOWN:
2615 e_client_key_send(ec,
2621 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_KEY_UP:
2622 e_client_key_send(ec,
2629 ERR("Not supported event_type(%d)", event_type);
2636 _remote_surface_cb_visibility_transfer(struct wl_client *client, struct wl_resource *resource, uint32_t visibility_type)
2638 E_Comp_Wl_Remote_Surface *remote_surface;
2640 remote_surface = wl_resource_get_user_data(resource);
2641 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2642 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2644 if (visibility_type == TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_INVISIBLE)
2646 _remote_surface_visible_set(remote_surface, EINA_FALSE);
2648 else if (visibility_type == TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_VISIBLE)
2650 _remote_surface_visible_set(remote_surface, EINA_TRUE);
2655 _remote_surface_cb_owner_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface_resource)
2657 E_Comp_Wl_Remote_Surface *remote_surface;
2658 E_Client *owner = NULL;
2660 remote_surface = wl_resource_get_user_data(resource);
2661 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2662 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2664 if (surface_resource)
2665 owner = wl_resource_get_user_data(surface_resource);
2667 if (remote_surface->owner)
2668 _remote_surface_client_set(remote_surface->owner, EINA_FALSE);
2670 remote_surface->owner = owner;
2671 eina_hash_del_by_data(_rsm->surface_hash, remote_surface);
2673 if ((owner) && (remote_surface->provider))
2675 eina_hash_add(_rsm->surface_hash, &owner, remote_surface);
2676 _remote_surface_client_set(remote_surface->owner, EINA_TRUE);
2679 if (remote_surface->provider)
2680 _remote_provider_onscreen_parent_calculate(remote_surface->provider);
2684 _remote_surface_cb_region_create(struct wl_client *client, struct wl_resource *remote_surface_resource, uint32_t id)
2686 struct wl_resource *resource;
2687 E_Comp_Wl_Remote_Surface *remote_surface;
2688 E_Comp_Wl_Remote_Region *region;
2689 E_Comp_Wl_Remote_Provider *provider;
2691 remote_surface = wl_resource_get_user_data(remote_surface_resource);
2692 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2693 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2695 resource = wl_resource_create(client,
2696 &tizen_remote_surface_region_interface,
2701 ERR("Could not create tizen remote region resource: %m");
2702 wl_client_post_no_memory(client);
2706 region = E_NEW(E_Comp_Wl_Remote_Region, 1);
2709 wl_client_post_no_memory(client);
2710 wl_resource_destroy(resource);
2713 region->remote_surface = remote_surface;
2714 region->resource = resource;
2715 region->geometry.x = -1;
2716 region->geometry.y = -1;
2717 region->geometry.w = -1;
2718 region->geometry.h = -1;
2719 remote_surface->regions = eina_list_append(remote_surface->regions, region);
2721 wl_resource_set_implementation(resource,
2722 &_remote_region_interface,
2724 _remote_region_cb_resource_destroy);
2726 //update provider's region rect list
2727 provider = remote_surface->provider;
2728 if ((provider) && (provider->onscreen_parent == remote_surface))
2730 _remote_provider_rect_add(provider, ®ion->geometry);
2735 _remote_surface_cb_release(struct wl_client *client, struct wl_resource *resource, struct wl_resource *remote_buffer_resource)
2737 E_Comp_Wl_Remote_Surface *remote_surface;
2738 E_Comp_Wl_Remote_Buffer *remote_buffer;
2740 remote_surface = wl_resource_get_user_data(resource);
2741 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2742 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2744 remote_buffer = _e_comp_wl_remote_buffer_get(remote_surface, remote_buffer_resource);
2745 EINA_SAFETY_ON_NULL_RETURN(remote_buffer);
2747 if (remote_surface->version >= 2)
2749 E_Comp_Wl_Buffer *buf = NULL;
2751 if (remote_buffer->ref.buffer &&
2752 remote_buffer->ref.buffer->resource)
2753 buf = remote_buffer->ref.buffer;
2755 e_comp_wl_buffer_reference(&remote_buffer->ref, NULL);
2757 /*Send release event to provider*/
2758 if (remote_surface->provider &&
2759 remote_surface->provider->buffer_mode &&
2760 buf && buf->busy == 0)
2762 if (remote_surface->provider->buffer_mode == 1 ||
2763 (remote_surface->provider->buffer_mode == 2 &&
2764 remote_surface->provider->vis_ref == 0))
2766 E_Client *ec = remote_surface->provider->common.ec;
2767 e_pixmap_buffer_clear(ec->pixmap, EINA_TRUE);
2774 _remote_surface_cb_remote_render_set(struct wl_client *client, struct wl_resource *resource, uint32_t set)
2776 E_Comp_Wl_Remote_Surface *remote_surface;
2777 E_Comp_Wl_Remote_Source *source = NULL;
2779 remote_surface = wl_resource_get_user_data(resource);
2780 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2781 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2783 source = remote_surface->source;
2784 if (!source) return;
2786 if (remote_surface->remote_render == set)
2789 remote_surface->remote_render = set;
2790 _remote_source_offscreen_set(source, set);
2794 _remote_surface_cb_changed_buffer_event_filter_set(struct wl_client *client,
2795 struct wl_resource *rsurf_res,
2796 enum tizen_remote_surface_changed_buffer_event_filter filter)
2798 E_Comp_Wl_Remote_Surface *rs;
2800 rs = wl_resource_get_user_data(rsurf_res);
2801 EINA_SAFETY_ON_NULL_RETURN(rs);
2802 EINA_SAFETY_ON_FALSE_RETURN(rs->valid);
2804 if (filter == TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_NONE)
2805 rs->changed_buff_ev_filter.use = EINA_FALSE;
2807 rs->changed_buff_ev_filter.use = EINA_TRUE;
2809 rs->changed_buff_ev_filter.filter = filter;
2811 RSMINF("use:%d filter:%u", NULL, NULL, "SURFACE", rs,
2812 rs->changed_buff_ev_filter.use,
2813 rs->changed_buff_ev_filter.filter);
2817 _remote_surface_cb_curr_buff_get(struct wl_client *client,
2818 struct wl_resource *rsurf_res,
2819 enum tizen_remote_surface_buffer_type buff_type,
2820 uint32_t req_serial)
2822 E_Comp_Wl_Remote_Surface *rs;
2825 rs = wl_resource_get_user_data(rsurf_res);
2826 EINA_SAFETY_ON_NULL_RETURN(rs);
2827 EINA_SAFETY_ON_FALSE_RETURN(rs->valid);
2829 RSMINF("buff_type:%u req_serial:%u", NULL, NULL, "SURFACE", rs,
2830 buff_type, req_serial);
2832 /* compare buffer type with filter value of changed_buffer event */
2833 res = _remote_surface_changed_buff_ev_filter_check(rs, buff_type);
2834 EINA_SAFETY_ON_FALSE_RETURN(res);
2836 /* setup request info before sending current buffer */
2837 rs->req_curr_buff.set = EINA_TRUE;
2838 rs->req_curr_buff.type = buff_type;
2839 rs->req_curr_buff.serial = req_serial;
2841 RSMINF("buff_type:%u req_serial:%u", NULL, NULL, "SURFACE", rs,
2842 buff_type, req_serial);
2844 /* send current buffer to the requesting client */
2845 res = _remote_surface_buff_send(rs);
2846 EINA_SAFETY_ON_FALSE_GOTO(res, err_cleanup);
2851 rs->req_curr_buff.set = EINA_FALSE;
2852 rs->req_curr_buff.type = 0;
2853 rs->req_curr_buff.serial = 0;
2856 static const struct tizen_remote_surface_interface _remote_surface_interface =
2858 _remote_surface_cb_destroy,
2859 _remote_surface_cb_redirect,
2860 _remote_surface_cb_unredirect,
2861 _remote_surface_cb_mouse_event_transfer,
2862 _remote_surface_cb_mouse_wheel_transfer,
2863 _remote_surface_cb_touch_event_transfer,
2864 _remote_surface_cb_touch_cancel_transfer,
2865 _remote_surface_cb_key_event_transfer,
2866 _remote_surface_cb_visibility_transfer,
2867 _remote_surface_cb_owner_set,
2868 _remote_surface_cb_region_create,
2869 _remote_surface_cb_release,
2870 _remote_surface_cb_remote_render_set,
2871 _remote_surface_cb_changed_buffer_event_filter_set,
2872 _remote_surface_cb_curr_buff_get,
2876 _remote_manager_cb_provider_create(struct wl_client *client, struct wl_resource *res_remote_manager, uint32_t id, struct wl_resource *surface_resource)
2878 struct wl_resource *resource;
2879 E_Comp_Wl_Remote_Provider *provider;
2884 EINA_SAFETY_ON_NULL_RETURN(_rsm);
2886 ec = wl_resource_get_user_data(surface_resource);
2887 EINA_SAFETY_ON_NULL_RETURN(ec);
2889 if (e_object_is_del(E_OBJECT(ec))) return;
2891 version = wl_resource_get_version(res_remote_manager);
2892 resource = wl_resource_create(client,
2893 &tizen_remote_surface_provider_interface,
2897 ERR("Could not create tizen remote surface provider resource: %m");
2898 wl_client_post_no_memory(client);
2902 provider = E_NEW(E_Comp_Wl_Remote_Provider, 1);
2905 wl_client_post_no_memory(client);
2906 wl_resource_destroy(resource);
2909 provider->common.ec = ec;
2910 provider->resource = resource;
2912 wl_resource_set_implementation(resource,
2913 &_remote_provider_interface,
2915 _remote_provider_cb_resource_destroy);
2917 eina_hash_add(_rsm->provider_hash, &ec, provider);
2919 RSMINF("Created resource(%p)",
2921 "PROVIDER", provider, resource);
2923 _remote_provider_client_set(ec, EINA_TRUE);
2924 _remote_provider_offscreen_set(provider, EINA_TRUE);
2926 /* send resource id */
2927 res_id = e_pixmap_res_id_get(ec->pixmap);
2928 tizen_remote_surface_provider_send_resource_id(resource, res_id);
2930 /* set buffer mode */
2931 provider->buffer_mode = e_config->rsm_buffer_release_mode;
2935 _remote_manager_cb_surface_create(struct wl_client *client,
2936 struct wl_resource *res_remote_manager,
2939 struct wl_resource *wl_tbm)
2941 struct wl_resource *resource;
2942 E_Comp_Wl_Remote_Surface *remote_surface;
2943 E_Comp_Wl_Remote_Provider *provider = NULL;
2944 E_Comp_Wl_Remote_Source *source = NULL;
2951 EINA_SAFETY_ON_NULL_RETURN(_rsm);
2953 version = wl_resource_get_version(res_remote_manager);
2954 resource = wl_resource_create(client,
2955 &tizen_remote_surface_interface,
2959 ERR("Could not create tizen remote surface resource: %m");
2960 wl_client_post_no_memory(client);
2964 remote_surface = E_NEW(E_Comp_Wl_Remote_Surface, 1);
2965 if (!remote_surface)
2967 wl_client_post_no_memory(client);
2968 wl_resource_destroy(resource);
2971 remote_surface->resource = resource;
2972 remote_surface->version = wl_resource_get_version(resource);
2973 remote_surface->redirect = EINA_FALSE;
2974 remote_surface->valid = EINA_FALSE;
2976 wl_resource_set_implementation(resource,
2977 &_remote_surface_interface,
2979 _remote_surface_cb_resource_destroy);
2981 ec = e_pixmap_find_client_by_res_id(res_id);
2984 ERR("Could not find client by res_id(%u)", res_id);
2990 ERR("wayland_tbm resource is NULL");
2994 provider = _remote_provider_find(ec);
2997 /* check the privilege for the client which wants to be the remote surface of normal UI client */
2998 wl_client_get_credentials(client, &pid, &uid, NULL);
2999 res = e_security_privilege_check(pid, uid, E_PRIVILEGE_INTERNAL_DEFAULT_PLATFORM);
3003 "Privilege Check Failed! DENY creating tizen_remote_surface pid:%d",
3008 if (version >= TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION)
3010 if (ec->comp_data->sub.data)
3012 ERR("Subsurface could not be source client");
3017 source = _remote_source_get(ec);
3018 if (!source) goto fail;
3022 ERR("Could not support tizen_remote_surface to client :%d", pid);
3027 remote_surface->provider = provider;
3028 remote_surface->source = source;
3029 remote_surface->wl_tbm = wl_tbm;
3031 /* Add destroy listener for wl_tbm resource */
3032 remote_surface->tbm_destroy_listener.notify = _remote_surface_cb_tbm_destroy;
3033 wl_resource_add_destroy_listener((struct wl_resource *)wl_tbm, &remote_surface->tbm_destroy_listener);
3036 provider->common.surfaces = eina_list_append(provider->common.surfaces, remote_surface);
3038 source->common.surfaces = eina_list_append(source->common.surfaces, remote_surface);
3040 RSMINF("Created resource(%p) ec(%p) provider(%p) source(%p) version(%d)",
3042 "SURFACE", remote_surface, resource, ec, provider, source, remote_surface->version);
3044 remote_surface->valid = EINA_TRUE;
3047 _remote_surface_ignore_output_transform_send(&provider->common);
3049 _remote_surface_ignore_output_transform_send(&source->common);
3054 tizen_remote_surface_send_missing(resource);
3059 _remote_manager_cb_surface_bind(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface_resource, struct wl_resource *remote_surface_resource)
3061 E_Comp_Wl_Remote_Surface *remote_surface;
3062 E_Comp_Wl_Remote_Provider *provider;
3063 E_Client *ec = NULL;
3065 remote_surface = wl_resource_get_user_data(remote_surface_resource);
3066 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
3067 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
3069 provider = remote_surface->provider;
3070 if (!provider) return;
3072 if (surface_resource)
3073 ec = wl_resource_get_user_data(surface_resource);
3075 _remote_surface_bind_client(remote_surface, ec);
3077 _remote_surface_ignore_output_transform_send(&provider->common);
3081 _remote_manager_cb_destroy(struct wl_client *client, struct wl_resource *resource)
3083 wl_resource_destroy(resource);
3086 static const struct tizen_remote_surface_manager_interface _remote_manager_interface =
3088 _remote_manager_cb_provider_create,
3089 _remote_manager_cb_surface_create,
3090 _remote_manager_cb_surface_bind,
3091 _remote_manager_cb_destroy,
3095 _remote_manager_cb_unbind(struct wl_resource *res_remote_manager)
3097 //nothing to do yet.
3101 _remote_manager_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t ver, uint32_t id)
3103 struct wl_resource *res_remote_manager;
3105 res_remote_manager = wl_resource_create(client,
3106 &tizen_remote_surface_manager_interface,
3109 EINA_SAFETY_ON_NULL_GOTO(res_remote_manager, err);
3111 wl_resource_set_implementation(res_remote_manager,
3112 &_remote_manager_interface,
3114 _remote_manager_cb_unbind);
3118 ERR("Could not create tizen_remote_surface_manager_interface res: %m");
3119 wl_client_post_no_memory(client);
3123 _image_save_type_check(E_Client *ec)
3125 if (ec->skip_save_img) return EINA_FALSE;
3127 if (e_policy_client_is_lockscreen(ec) ||
3128 e_policy_client_is_home_screen(ec) ||
3129 e_policy_client_is_quickpanel(ec) ||
3130 e_policy_client_is_volume(ec) ||
3131 e_policy_client_is_volume_tv(ec) ||
3132 e_policy_client_is_floating(ec) ||
3133 e_policy_client_is_cursor(ec) ||
3134 e_policy_client_is_subsurface(ec) ||
3135 e_policy_client_is_cbhm(ec) ||
3136 e_policy_client_is_toast_popup(ec) ||
3137 e_policy_client_is_keyboard(ec) ||
3138 e_policy_client_is_keyboard_sub(ec) ||
3139 e_policy_client_is_keyboard_magnifier(ec))
3146 _e_comp_wl_remote_cb_client_iconify(void *data, E_Client *ec)
3148 E_Comp_Wl_Remote_Source *source;
3150 if (!(source = _remote_source_find(ec)))
3152 if (ec->ignored) return;
3153 if (!_image_save_type_check(ec)) return;
3154 if (e_object_is_del(E_OBJECT(ec))) return;
3156 source = E_NEW(E_Comp_Wl_Remote_Source, 1);
3157 EINA_SAFETY_ON_NULL_RETURN(source);
3159 source->common.ec = ec;
3160 eina_hash_add(_rsm->source_hash, &ec, source);
3163 _remote_source_save_start(source);
3167 _e_comp_wl_remote_cb_client_uniconify(void *data, E_Client *ec)
3169 _remote_source_save_start_cancel(ec);
3173 _e_comp_wl_remote_cb_client_del(void *data, E_Client *ec)
3175 E_Comp_Wl_Remote_Provider *provider;
3176 E_Comp_Wl_Remote_Source *source;
3177 E_Comp_Wl_Remote_Surface *remote_surface;
3179 if ((provider = eina_hash_find(_rsm->provider_hash, &ec)))
3181 eina_hash_del(_rsm->provider_hash, &ec, provider);
3182 EINA_LIST_FREE(provider->common.surfaces, remote_surface)
3184 if (remote_surface->provider == provider)
3186 /* unset remote buffer from provider */
3187 if (remote_surface->bind_ec)
3188 _remote_surface_bind_client(remote_surface, NULL);
3190 remote_surface->provider = NULL;
3191 //notify of this ejection to remote surface_resource
3192 tizen_remote_surface_send_missing(remote_surface->resource);
3195 _remote_provider_offscreen_set(provider, EINA_FALSE);
3196 wl_resource_set_user_data(provider->resource, NULL);
3200 if ((source = _remote_source_find(ec)))
3202 _remote_source_destroy(source);
3205 if ((remote_surface = eina_hash_find(_rsm->surface_hash, &ec)))
3207 eina_hash_del(_rsm->surface_hash, &ec, remote_surface);
3208 if (remote_surface->owner == ec)
3209 remote_surface->owner = NULL;
3210 if (remote_surface->provider)
3211 _remote_provider_onscreen_parent_calculate(remote_surface->provider);
3214 if ((remote_surface = eina_hash_find(_rsm->bind_surface_hash, &ec)))
3216 eina_hash_del(_rsm->bind_surface_hash, &ec, remote_surface);
3217 if (remote_surface->bind_ec == ec)
3218 _remote_surface_bind_client(remote_surface, NULL);
3223 _e_comp_wl_remote_cb_hook_action_change(void *d EINA_UNUSED, E_Process *epro, void *user)
3225 E_Process_Action act;
3226 E_Client *ec = NULL;
3227 E_Client *base_ec = NULL;
3230 act = *(E_Process_Action*)user;
3232 if (act == E_PROCESS_ACT_ACTIVATE)
3234 EINA_LIST_FOREACH(epro->ec_list, l, ec)
3236 _remote_source_save_start_cancel(ec);
3237 ec->saved_img = EINA_FALSE;
3240 else if (act == E_PROCESS_ACT_DEACTIVATE)
3242 EINA_LIST_FOREACH(epro->ec_list, l, ec)
3248 if (!_image_save_type_check(ec))
3257 E_Comp_Wl_Remote_Source *source;
3259 if (!(source = _remote_source_find(base_ec)))
3261 if (base_ec->ignored) return;
3262 if (!_image_save_type_check(base_ec)) return;
3263 if (e_object_is_del(E_OBJECT(base_ec))) return;
3265 source = E_NEW(E_Comp_Wl_Remote_Source, 1);
3266 EINA_SAFETY_ON_NULL_RETURN(source);
3268 source->common.ec = base_ec;
3269 eina_hash_add(_rsm->source_hash, &base_ec, source);
3272 _remote_source_save_start(source);
3277 _e_comp_wl_remote_cb_visibility_change(void *data, int type, void *event)
3279 E_Event_Client *ev = event;
3281 E_Comp_Wl_Remote_Surface *remote_surface;
3283 EINA_SAFETY_ON_NULL_RETURN_VAL(_rsm, ECORE_CALLBACK_PASS_ON);
3285 E_Process_Hook *process_hook;
3287 if (!_rsm->process_hooks)
3289 process_hook = e_process_hook_add(E_PROCESS_HOOK_ACTION_CHANGE, _e_comp_wl_remote_cb_hook_action_change, NULL);
3290 if (process_hook) _rsm->process_hooks = eina_list_append(_rsm->process_hooks, process_hook);
3294 if (!ec) return ECORE_CALLBACK_PASS_ON;
3296 if (e_object_is_del(E_OBJECT(ec))) return ECORE_CALLBACK_PASS_ON;
3298 if ((remote_surface = eina_hash_find(_rsm->surface_hash, &ec)))
3300 _remote_provider_onscreen_parent_calculate(remote_surface->provider);
3303 return ECORE_CALLBACK_PASS_ON;
3307 _e_comp_wl_remote_buffer_cb_destroy(struct wl_listener *listener, void *data)
3309 E_Comp_Wl_Remote_Buffer *remote_buffer;
3310 E_Comp_Wl_Remote_Surface *remote_surface;
3312 remote_buffer = container_of(listener, E_Comp_Wl_Remote_Buffer, destroy_listener);
3313 if (!remote_buffer) return;
3316 if (remote_buffer->destroy_listener.notify)
3318 wl_list_remove(&remote_buffer->destroy_listener.link);
3319 remote_buffer->destroy_listener.notify = NULL;
3322 remote_surface = remote_buffer->remote_surface;
3324 remote_surface->send_remote_bufs = eina_list_remove(remote_surface->send_remote_bufs, remote_buffer);
3326 e_comp_wl_buffer_reference(&remote_buffer->ref, NULL);
3327 free(remote_buffer);
3330 static E_Comp_Wl_Remote_Buffer *
3331 _e_comp_wl_remote_buffer_get(E_Comp_Wl_Remote_Surface *remote_surface, struct wl_resource *remote_buffer_resource)
3333 E_Comp_Wl_Remote_Buffer *remote_buffer = NULL;
3334 struct wl_listener *listener;
3336 listener = wl_resource_get_destroy_listener(remote_buffer_resource, _e_comp_wl_remote_buffer_cb_destroy);
3338 return container_of(listener, E_Comp_Wl_Remote_Buffer, destroy_listener);
3340 if (!(remote_buffer = E_NEW(E_Comp_Wl_Remote_Buffer, 1))) return NULL;
3342 remote_buffer->remote_surface = remote_surface;
3343 remote_buffer->resource = remote_buffer_resource;
3344 remote_buffer->destroy_listener.notify = _e_comp_wl_remote_buffer_cb_destroy;
3345 wl_resource_add_destroy_listener(remote_buffer->resource, &remote_buffer->destroy_listener);
3347 remote_surface->send_remote_bufs = eina_list_append(remote_surface->send_remote_bufs, remote_buffer);
3349 return remote_buffer;
3353 _e_comp_wl_remote_surface_source_update(E_Comp_Wl_Remote_Source *source, E_Comp_Wl_Buffer *buffer)
3355 E_Comp_Wl_Remote_Surface *remote_surface;
3358 if ((!source) || (!buffer)) return;
3360 EINA_LIST_FOREACH(source->common.surfaces, l, remote_surface)
3362 if (remote_surface->version < TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION)
3365 if (!remote_surface->redirect) continue;
3367 _remote_surface_changed_buff_protocol_send(remote_surface,
3368 TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM,
3377 _e_comp_wl_remote_surface_dummy_fd_get(void)
3379 int fd = 0, blen = 0, len = 0;
3383 blen = sizeof(tmp) - 1;
3385 path = e_util_env_get("XDG_RUNTIME_DIR");
3386 if (!path) return -1;
3391 strncpy(tmp, path, len + 1);
3392 strncat(tmp, "/enlightenment_rsm_dummy_fdXXXXXX", 34);
3401 if ((fd = mkstemp(tmp)) < 0)
3410 _e_comp_wl_remote_surface_state_buffer_set(E_Comp_Wl_Surface_State *state, E_Comp_Wl_Buffer *buffer)
3412 if (state->buffer == buffer) return;
3414 wl_list_remove(&state->buffer_destroy_listener.link);
3415 state->buffer = buffer;
3417 wl_signal_add(&state->buffer->destroy_signal,
3418 &state->buffer_destroy_listener);
3422 _e_comp_wl_remote_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
3424 E_Comp_Wl_Remote_Provider *provider;
3425 E_Comp_Wl_Remote_Source *source;
3426 E_Comp_Wl_Remote_Surface *surface;
3427 struct wl_resource *cb;
3428 Eina_Rectangle *dmg;
3429 int x = 0, y = 0, sx = 0, sy = 0;
3430 E_Comp_Wl_Buffer *buffer;
3432 E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport;
3434 if (e_object_is_del(E_OBJECT(ec))) return;
3436 if (vp->buffer.transform != state->buffer_viewport.buffer.transform)
3438 int transform_change = (4 + state->buffer_viewport.buffer.transform - vp->buffer.transform) & 0x3;
3440 ELOGF("TRANSFORM", "buffer_transform changed: old(%d) new(%d)",
3442 vp->buffer.transform, state->buffer_viewport.buffer.transform);
3444 if (transform_change == vp->wait_for_transform_change)
3445 vp->wait_for_transform_change = 0;
3448 ec->comp_data->scaler.buffer_viewport = state->buffer_viewport;
3450 if (state->new_attach)
3451 e_comp_wl_surface_attach(ec, state->buffer);
3453 _e_comp_wl_remote_surface_state_buffer_set(state, NULL);
3455 if (state->new_attach)
3457 x = ec->client.x, y = ec->client.y;
3459 ec->w = ec->client.w = state->bw;
3460 ec->h = ec->client.h = state->bh;
3462 if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.configure))
3463 ec->comp_data->shell.configure(ec->comp_data->shell.surface,
3464 x, y, ec->w, ec->h);
3471 state->new_attach = EINA_FALSE;
3473 /* send previous frame done */
3474 EINA_LIST_FOREACH_SAFE(ec->comp_data->frames, l, ll, cb)
3476 wl_callback_send_done(cb, ecore_time_unix_get() * 1000);
3477 wl_resource_destroy(cb);
3480 ec->comp_data->frames = eina_list_merge(ec->comp_data->frames,
3482 state->frames = NULL;
3484 /* clear stored damages... */
3485 EINA_LIST_FREE(state->buffer_damages, dmg)
3486 eina_rectangle_free(dmg);
3488 EINA_LIST_FREE(state->damages, dmg)
3489 eina_rectangle_free(dmg);
3491 state->buffer_viewport.changed = 0;
3493 /* send remote buffer to remote surfaces */
3494 buffer = e_pixmap_resource_get(ec->pixmap);
3497 if ((provider = _remote_provider_find(ec)))
3499 EINA_LIST_FOREACH(provider->common.surfaces, l, surface)
3501 if (!surface->redirect) continue;
3502 if (surface->bind_ec)
3504 surface->bind_ec->comp_data->pending.buffer_viewport = ec->comp_data->scaler.buffer_viewport;
3506 _e_comp_wl_remote_surface_state_buffer_set(&surface->bind_ec->comp_data->pending, buffer);
3507 surface->bind_ec->comp_data->pending.sx = sx;
3508 surface->bind_ec->comp_data->pending.sy = sy;
3509 surface->bind_ec->comp_data->pending.new_attach = EINA_TRUE;
3511 e_comp_wl_surface_commit(surface->bind_ec);
3513 /* need to prepare hwc whenever buffer changed */
3514 e_comp_render_queue();
3518 _remote_surface_changed_buff_protocol_send(surface,
3519 TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM,
3527 else if ((source = _remote_source_find(ec)))
3529 _e_comp_wl_remote_surface_source_update(source, buffer);
3532 /* send frame done */
3533 e_pixmap_image_clear(ec->pixmap, 1);
3538 _e_comp_wl_remote_surface_subsurface_commit(E_Comp_Wl_Remote_Provider *parent_provider,
3541 E_Comp_Wl_Subsurf_Data *sdata;
3542 E_Comp_Wl_Remote_Surface *onscreen_parent;
3544 Eina_Rectangle *rect;
3547 Eina_Bool first_skip = EINA_TRUE;
3548 E_Comp_Wl_Buffer *buffer;
3550 if (!e_comp_wl_subsurface_commit(ec)) return EINA_FALSE;
3552 buffer = e_pixmap_resource_get(ec->pixmap);
3553 if (!buffer) return EINA_TRUE;
3555 if (buffer->type != E_COMP_WL_BUFFER_TYPE_SHM) return EINA_TRUE;
3557 /* TODO : store and use multiple onscreen_parent for geometry calculation */
3558 onscreen_parent = parent_provider->onscreen_parent;
3559 if (!onscreen_parent) return EINA_TRUE;
3561 if (!evas_object_visible_get(ec->frame)) return EINA_TRUE;
3563 sdata = ec->comp_data->sub.data;
3564 evas_object_geometry_get(ec->frame, &fx, &fy, &fw, &fh);
3566 EINA_LIST_FOREACH(parent_provider->common.ec->comp_data->remote_surface.regions, l, rect)
3568 E_Comp_Wl_Remote_Region *region;
3570 region = container_of(rect, E_Comp_Wl_Remote_Region, geometry);
3572 x = sdata->position.x + rect->x;
3573 y = sdata->position.y + rect->y;
3574 if (onscreen_parent->owner)
3576 x += onscreen_parent->owner->x;
3577 y += onscreen_parent->owner->y;
3580 if ((fx == x) && (fy == y) && (first_skip))
3582 first_skip = EINA_FALSE;
3586 w = ec->comp_data->width_from_viewport;
3587 h = ec->comp_data->height_from_viewport;
3590 * w = (int) (w * ((double)rect->w / parent_provider->ec->w));
3591 * h = (int) (h * ((double)rect->h / parent_provider->ec->h));
3594 if (!region->mirror)
3596 region->mirror = e_comp_object_util_mirror_add(ec->frame);
3597 evas_object_layer_set(region->mirror, ec->layer);
3598 evas_object_stack_below(region->mirror, ec->frame);
3599 evas_object_show(region->mirror);
3600 evas_object_event_callback_add(region->mirror, EVAS_CALLBACK_DEL, _remote_region_cb_mirror_del, region);
3602 if (!region->mirror) continue;
3604 evas_object_move(region->mirror, x, y);
3605 evas_object_resize(region->mirror, w, h);
3610 #endif /* HAVE_REMOTE_SURFACE */
3613 e_comp_wl_remote_surface_bound_provider_ec_get(E_Client *ec)
3615 #ifdef HAVE_REMOTE_SURFACE
3616 E_Comp_Wl_Remote_Surface *remote_surface;
3618 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3619 EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), NULL);
3620 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, NULL);
3622 remote_surface = eina_hash_find(_rsm->bind_surface_hash, &ec);
3623 if (!remote_surface || !remote_surface->provider) return NULL;
3625 return remote_surface->provider->common.ec;
3626 #endif /* HAVE_REMOTE_SURFACE */
3630 e_comp_wl_remote_surface_commit(E_Client *ec)
3632 #ifdef HAVE_REMOTE_SURFACE
3633 E_Comp_Wl_Remote_Provider *provider;
3634 E_Comp_Wl_Remote_Source *source = NULL;
3635 E_Comp_Wl_Subsurf_Data *sdata, *ssdata;
3636 E_Client *offscreen_parent;
3638 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
3639 EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), EINA_FALSE);
3640 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
3642 source = _remote_source_find(ec);
3645 if (source->common.is_offscreen)
3647 _e_comp_wl_remote_surface_state_commit(ec, &ec->comp_data->pending);
3651 //send update to remote_surface of source client
3652 _e_comp_wl_remote_surface_source_update(source, ec->comp_data->pending.buffer);
3654 //do normal commit callback process
3658 /* subsurface case */
3659 if ((sdata = ec->comp_data->sub.data))
3661 /* check for valid subcompositor data */
3665 if (!(ssdata = sdata->parent->comp_data->sub.data))
3668 if (!ssdata->remote_surface.offscreen_parent)
3671 offscreen_parent = ssdata->remote_surface.offscreen_parent;
3673 provider = _remote_provider_find(offscreen_parent);
3674 if (!provider) return EINA_FALSE;
3676 if (!_e_comp_wl_remote_surface_subsurface_commit(provider, ec))
3681 if (!(provider = _remote_provider_find(ec)))
3684 _e_comp_wl_remote_surface_state_commit(ec, &ec->comp_data->pending);
3689 #endif /* HAVE_REMOTE_SURFACE */
3693 e_comp_wl_remote_surface_image_save(E_Client *ec)
3695 #ifdef HAVE_REMOTE_SURFACE
3696 E_Comp_Wl_Remote_Source *src;
3698 if (!e_config->save_win_buffer) return;
3699 if (!e_config->hold_prev_win_img) return;
3700 if (ec->saved_img) return;
3701 if (ec->ignored) return;
3702 if (!_image_save_type_check(ec)) return;
3704 src = _remote_source_get(ec);
3705 EINA_SAFETY_ON_NULL_GOTO(src, end);
3707 _remote_source_save_start(src);
3711 #endif /* HAVE_REMOTE_SURFACE */
3715 e_comp_wl_remote_surface_image_save_skip_set(E_Client *ec, Eina_Bool set)
3717 if (!e_config->save_win_buffer) return;
3718 if (e_object_is_del(E_OBJECT(ec))) return;
3720 ec->skip_save_img = set;
3724 e_comp_wl_remote_surface_image_save_skip_get(E_Client *ec)
3726 if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
3727 return ec->skip_save_img;
3731 e_comp_wl_remote_surface_debug_info_get(Eldbus_Message_Iter *iter)
3733 #ifdef HAVE_REMOTE_SURFACE
3734 Eldbus_Message_Iter *line_array;
3735 Eina_Iterator *hash_iter;
3736 E_Comp_Wl_Remote_Provider *provider;
3737 E_Comp_Wl_Remote_Source *source;
3739 char info_str[1024];
3741 eldbus_message_iter_arguments_append(iter, "as", &line_array);
3744 eldbus_message_iter_basic_append(line_array,
3746 "Remote Surface not initialized..");
3747 eldbus_message_iter_container_close(iter, line_array);
3752 hash_iter = eina_hash_iterator_data_new(_rsm->provider_hash);
3753 EINA_ITERATOR_FOREACH(hash_iter, provider)
3755 E_Client *ec = provider->common.ec;
3756 E_Comp_Wl_Remote_Surface *remote_surface;
3761 snprintf(info_str, sizeof(info_str),
3762 "%10s [%d] %8p win(0x%08zx) res(%d) pid(%d) vis(%d) name(%s)",
3763 "PROVIDER", idx++, provider,
3764 e_client_util_win_get(ec),
3765 e_pixmap_res_id_get(ec->pixmap),
3768 e_client_util_name_get(ec)?:ec->icccm.class?:"NO NAME");
3769 eldbus_message_iter_basic_append(line_array, 's', info_str);
3771 if (provider->common.surfaces)
3773 snprintf(info_str, sizeof(info_str), "%7s", "│");
3774 eldbus_message_iter_basic_append(line_array, 's', info_str);
3777 EINA_LIST_FOREACH(provider->common.surfaces, l, remote_surface)
3779 struct wl_client *wc = NULL;
3780 E_Client *owner = NULL;
3783 Eina_Bool is_last = 0;
3785 if (!remote_surface->resource) continue;
3787 owner = remote_surface->owner;
3789 owner = remote_surface->bind_ec;
3791 wc = wl_resource_get_client(remote_surface->resource);
3793 wl_client_get_credentials(wc, &pid, NULL, NULL);
3795 if ((eina_list_last(provider->common.surfaces) == l))
3796 is_last = EINA_TRUE;
3798 snprintf(info_str, sizeof(info_str),
3799 "%10s CONSUMER [%d] %8p ec(%8p) win(0x%08zx) pid(%d) vis(%d) redirected(%d) name(%s)",
3800 is_last? "└─" : "├─", s_idx++, remote_surface,
3801 owner ? owner : NULL,
3802 owner ? e_client_util_win_get(owner) : 0,
3804 remote_surface->visible,
3805 remote_surface->redirect,
3806 owner? e_client_util_name_get(owner)?:owner->icccm.class?:"NO NAME":"NO OWNER"
3808 eldbus_message_iter_basic_append(line_array, 's', info_str);
3810 eldbus_message_iter_basic_append(line_array, 's', "");
3812 eina_iterator_free(hash_iter);
3816 hash_iter = eina_hash_iterator_data_new(_rsm->source_hash);
3817 EINA_ITERATOR_FOREACH(hash_iter, source)
3819 E_Client *ec = source->common.ec;
3820 E_Comp_Wl_Remote_Surface *remote_surface;
3824 snprintf(info_str, sizeof(info_str),
3825 "%10s [%d] %8p win(0x%08zx) res(%d) pid(%d) offscreen(%d) name(%s)",
3826 "SOURCE", idx++, source,
3827 e_client_util_win_get(ec),
3828 e_pixmap_res_id_get(ec->pixmap),
3830 source->offscreen_ref,
3831 e_client_util_name_get(ec)?:ec->icccm.class?:"NO NAME");
3832 eldbus_message_iter_basic_append(line_array, 's', info_str);
3834 if (source->common.surfaces)
3836 snprintf(info_str, sizeof(info_str), "%7s", "│");
3837 eldbus_message_iter_basic_append(line_array, 's', info_str);
3840 EINA_LIST_FOREACH(source->common.surfaces, l, remote_surface)
3842 struct wl_client *wc = NULL;
3843 E_Client *owner = NULL;
3846 Eina_Bool is_last = 0;
3848 if (!remote_surface->resource) continue;
3850 owner = remote_surface->owner;
3852 owner = remote_surface->bind_ec;
3854 wc = wl_resource_get_client(remote_surface->resource);
3856 wl_client_get_credentials(wc, &pid, NULL, NULL);
3858 if ((eina_list_last(source->common.surfaces) == l))
3859 is_last = EINA_TRUE;
3861 snprintf(info_str, sizeof(info_str),
3862 "%10s CONSUMER [%d] %8p ec(%8p) win(0x%08zx) pid(%d) vis(%d) redirected(%d) name(%s)",
3863 is_last? "└─" : "├─", s_idx++, remote_surface,
3864 owner ? owner : NULL,
3865 owner ? e_client_util_win_get(owner) : 0,
3867 remote_surface->visible,
3868 remote_surface->redirect,
3869 owner? e_client_util_name_get(owner)?:owner->icccm.class?:"NO NAME":"NO OWNER"
3871 eldbus_message_iter_basic_append(line_array, 's', info_str);
3873 eldbus_message_iter_basic_append(line_array, 's', "");
3875 eina_iterator_free(hash_iter);
3877 eldbus_message_iter_container_close(iter, line_array);
3879 Eldbus_Message_Iter *line_array;
3881 eldbus_message_iter_arguments_append(iter, "as", &line_array);
3882 eldbus_message_iter_basic_append(line_array,
3884 "Enlightenment doesn't support remote surface");
3885 eldbus_message_iter_container_close(iter, line_array);
3889 #undef E_CLIENT_HOOK_APPEND
3890 #define E_CLIENT_HOOK_APPEND(l, t, cb, d) \
3893 E_Client_Hook *_h; \
3894 _h = e_client_hook_add(t, cb, d); \
3896 l = eina_list_append(l, _h); \
3901 e_comp_wl_remote_surface_init(void)
3903 #ifdef HAVE_REMOTE_SURFACE
3904 E_Comp_Wl_Remote_Manager *rs_manager = NULL;
3906 EINA_SAFETY_ON_NULL_RETURN(e_comp_wl);
3907 EINA_SAFETY_ON_NULL_RETURN(e_comp_wl->wl.disp);
3908 EINA_SAFETY_ON_NULL_RETURN(e_comp->wl_comp_data->tbm.server);
3910 rs_manager = E_NEW(E_Comp_Wl_Remote_Manager, 1);
3911 EINA_SAFETY_ON_NULL_RETURN(rs_manager);
3913 rs_manager->global = wl_global_create(e_comp_wl->wl.disp,
3914 &tizen_remote_surface_manager_interface,
3917 _remote_manager_cb_bind);
3920 E_CLIENT_HOOK_APPEND(rs_manager->client_hooks, E_CLIENT_HOOK_DEL, _e_comp_wl_remote_cb_client_del, NULL);
3921 if (e_config->save_win_buffer)
3923 E_CLIENT_HOOK_APPEND(rs_manager->client_hooks, E_CLIENT_HOOK_ICONIFY, _e_comp_wl_remote_cb_client_iconify, NULL);
3924 E_CLIENT_HOOK_APPEND(rs_manager->client_hooks, E_CLIENT_HOOK_UNICONIFY, _e_comp_wl_remote_cb_client_uniconify, NULL);
3928 E_LIST_HANDLER_APPEND(rs_manager->event_hdlrs,
3929 E_EVENT_CLIENT_VISIBILITY_CHANGE,
3930 _e_comp_wl_remote_cb_visibility_change, rs_manager);
3932 rs_manager->provider_hash = eina_hash_pointer_new(NULL);
3933 rs_manager->surface_hash = eina_hash_pointer_new(NULL);
3934 rs_manager->source_hash = eina_hash_pointer_new(NULL);
3935 rs_manager->bind_surface_hash = eina_hash_pointer_new(NULL);
3936 rs_manager->dummy_fd = _e_comp_wl_remote_surface_dummy_fd_get();
3938 if (rs_manager->dummy_fd == -1)
3940 ERR("it's FATAL error, remote surface can't send remote buffer without dummy_fd...");
3942 e_comp_wl_remote_surface_shutdown();
3946 RSMINF("dummy_fd created %d", NULL, NULL, "MANAGER", rs_manager, rs_manager->dummy_fd);
3950 E_EVENT_REMOTE_SURFACE_PROVIDER_VISIBILITY_CHANGE = ecore_event_type_new();
3951 #endif /* HAVE_REMOTE_SURFACE */
3955 e_comp_wl_remote_surface_shutdown(void)
3957 #ifdef HAVE_REMOTE_SURFACE
3958 E_Comp_Wl_Remote_Manager *rsm;
3959 E_Comp_Wl_Remote_Provider *provider;
3960 E_Comp_Wl_Remote_Source *source;
3961 E_Comp_Wl_Remote_Surface *remote_surface;
3969 it = eina_hash_iterator_data_new(rsm->provider_hash);
3970 EINA_ITERATOR_FOREACH(it, provider)
3972 EINA_LIST_FREE(provider->common.surfaces, remote_surface)
3974 remote_surface->provider = NULL;
3975 wl_resource_destroy(remote_surface->resource);
3977 wl_resource_destroy(provider->resource);
3979 eina_iterator_free(it);
3981 it = eina_hash_iterator_data_new(rsm->source_hash);
3982 EINA_ITERATOR_FOREACH(it, source)
3984 EINA_LIST_FREE(source->common.surfaces, remote_surface)
3986 remote_surface->source = NULL;
3987 wl_resource_destroy(remote_surface->resource);
3989 _remote_source_destroy(source);
3991 eina_iterator_free(it);
3993 if (rsm->dummy_fd != -1)
3994 close(rsm->dummy_fd);
3996 E_FREE_LIST(rsm->process_hooks, e_process_hook_del);
3998 E_FREE_FUNC(rsm->provider_hash, eina_hash_free);
3999 E_FREE_FUNC(rsm->surface_hash, eina_hash_free);
4000 E_FREE_FUNC(rsm->source_hash, eina_hash_free);
4001 E_FREE_FUNC(rsm->bind_surface_hash, eina_hash_free);
4003 E_FREE_LIST(rsm->client_hooks, e_client_hook_del);
4004 E_FREE_LIST(rsm->event_hdlrs, ecore_event_handler_del);
4005 wl_global_destroy(rsm->global);
4007 #endif /* HAVE_REMOTE_SURFACE */