1 #include "e_comp_wl_rsm_intern.h"
2 #include "e_device_intern.h"
3 #include "e_client_intern.h"
4 #include "e_process_intern.h"
5 #include "e_comp_wl_intern.h"
6 #include "e_comp_wl_subsurface_intern.h"
7 #include "e_comp_wl_tbm_intern.h"
8 #include "e_privilege_intern.h"
9 #include "e_policy_intern.h"
10 #include "e_comp_object_intern.h"
11 #include "e_zone_intern.h"
12 #include "e_utils_intern.h"
13 #include "e_security_intern.h"
15 #include <tizen-remote-surface-server-protocol.h>
16 #include <tbm_surface.h>
17 #include <tbm_surface_internal.h>
18 #include <wayland-tbm-server.h>
19 #include <tizen-extension-server-protocol.h>
23 #include <Ecore_File.h>
25 #define RSMINF(f, ec, str, obj, x...) \
28 ELOGF("RSM","%10.10s|%8p|"f, \
29 (ec), (str), (obj), ##x); \
33 #define RSMDBG(f, ec, str, obj, x...) \
36 ELOGFD("RSM", "%10.10s|%8p|"f, \
37 (ec), (str), (obj), ##x); \
41 #define container_of(ptr, type, member) \
43 const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \
44 (type *)( (char *)__mptr - offsetof(type,member) ); \
47 E_API int E_EVENT_REMOTE_SURFACE_PROVIDER_VISIBILITY_CHANGE = -1;
49 typedef struct _E_Comp_Wl_Remote_Manager E_Comp_Wl_Remote_Manager;
50 typedef struct _E_Comp_Wl_Remote_Common E_Comp_Wl_Remote_Common;
51 typedef struct _E_Comp_Wl_Remote_Provider E_Comp_Wl_Remote_Provider;
52 typedef struct _E_Comp_Wl_Remote_Source E_Comp_Wl_Remote_Source;
53 typedef struct _E_Comp_Wl_Remote_Surface E_Comp_Wl_Remote_Surface;
54 typedef struct _E_Comp_Wl_Remote_Region E_Comp_Wl_Remote_Region;
55 typedef struct _E_Comp_Wl_Remote_Buffer E_Comp_Wl_Remote_Buffer;
57 struct _E_Comp_Wl_Remote_Manager
59 struct wl_global *global;
61 Eina_Hash *provider_hash;
62 Eina_Hash *consumer_hash;
63 Eina_Hash *source_hash;
64 Eina_Hash *bind_surface_hash;
65 Eina_List *event_hdlrs;
66 Eina_List *client_hooks;
67 Eina_List *process_hooks;
69 E_Comp_Object_Hook *effect_end;
72 int dummy_fd; /* tizen_remote_surface@chagned_buffer need valid fd when it send tbm surface */
75 /* common structure of provider and source */
76 struct _E_Comp_Wl_Remote_Common
81 Eina_Bool is_offscreen;
82 Eina_Bool ignore_output_transform;
86 struct _E_Comp_Wl_Remote_Provider
88 E_Comp_Wl_Remote_Common common;
90 struct wl_resource *resource;
92 E_Comp_Wl_Remote_Surface *onscreen_parent;
96 uint32_t input_event_filter;
100 /* normal UI client */
101 struct _E_Comp_Wl_Remote_Source
103 E_Comp_Wl_Remote_Common common;
105 const char *image_path;
111 /* widget viewer or task-manager client */
112 struct _E_Comp_Wl_Remote_Surface
114 struct wl_resource *resource;
115 struct wl_resource *wl_tbm;
116 struct wl_listener tbm_destroy_listener;
118 E_Comp_Wl_Remote_Provider *provider;
119 E_Comp_Wl_Remote_Source *source;
129 Eina_Bool remote_render;
133 Eina_List *send_remote_bufs;
138 enum tizen_remote_surface_changed_buffer_event_filter filter;
139 } changed_buff_ev_filter;
144 enum tizen_remote_surface_buffer_type type;
148 Eina_Bool need_prebind;
153 struct _E_Comp_Wl_Remote_Region
155 struct wl_resource *resource;
157 E_Comp_Wl_Remote_Surface *remote_surface;
158 Eina_Rectangle geometry;
162 struct _E_Comp_Wl_Remote_Buffer
164 E_Comp_Wl_Buffer_Ref ref;
165 struct wl_resource *resource;
166 struct wl_listener destroy_listener;
168 E_Comp_Wl_Remote_Surface *remote_surface;
171 static E_Comp_Wl_Remote_Manager *_rsm = NULL;
173 static void _e_comp_wl_remote_surface_state_buffer_set(E_Comp_Wl_Surface_State *state, E_Comp_Wl_Buffer *buffer);
174 static void _e_comp_wl_remote_buffer_cb_destroy(struct wl_listener *listener, void *data);
175 static E_Comp_Wl_Remote_Buffer *_e_comp_wl_remote_buffer_get(E_Comp_Wl_Remote_Surface *remote_surface,
176 struct wl_resource *remote_buffer_resource);
177 static void _remote_surface_region_clear(E_Comp_Wl_Remote_Surface *remote_surface);
178 static void _remote_surface_ignore_output_transform_send(E_Comp_Wl_Remote_Common *common);
180 static Ecore_Device *
181 _device_get_by_identifier(const char *identifier, Ecore_Device_Class clas)
183 Ecore_Device *dev = NULL;
184 const Eina_List *devices, *l;
186 devices = ecore_device_list();
187 EINA_LIST_FOREACH(devices, l, dev)
189 if (clas != ecore_device_class_get(dev)) continue;
190 if (!e_util_strcmp(identifier, ecore_device_identifier_get(dev)))
197 static Ecore_Device_Class
198 _device_class_convert_to_ecore(uint32_t clas)
202 case TIZEN_INPUT_DEVICE_CLAS_MOUSE:
203 return ECORE_DEVICE_CLASS_MOUSE;
204 case TIZEN_INPUT_DEVICE_CLAS_TOUCHSCREEN:
205 return ECORE_DEVICE_CLASS_TOUCH;
206 case TIZEN_INPUT_DEVICE_CLAS_KEYBOARD:
207 return ECORE_DEVICE_CLASS_KEYBOARD;
209 return ECORE_DEVICE_CLASS_NONE;
214 _remote_region_mirror_clear(E_Comp_Wl_Remote_Region *region)
217 if (!region->mirror) return;
219 evas_object_del(region->mirror);
223 _remote_provider_rect_add(E_Comp_Wl_Remote_Provider *provider, Eina_Rectangle *rect)
227 ec = provider->common.ec;
229 if (!ec->comp_data) return;
231 ec->comp_data->remote_surface.regions =
232 eina_list_remove(ec->comp_data->remote_surface.regions,
234 ec->comp_data->remote_surface.regions =
235 eina_list_append(ec->comp_data->remote_surface.regions,
240 _remote_provider_rect_del(E_Comp_Wl_Remote_Provider *provider, Eina_Rectangle *rect)
244 ec = provider->common.ec;
246 if (!ec->comp_data) return;
248 ec->comp_data->remote_surface.regions =
249 eina_list_remove(ec->comp_data->remote_surface.regions,
254 _remote_provider_rect_clear(E_Comp_Wl_Remote_Provider *provider)
258 ec = provider->common.ec;
260 if (!ec->comp_data) return;
262 /* TODO : remove it from here after supporting multiple onscreen surface */
263 _remote_surface_region_clear(provider->onscreen_parent);
265 ec->comp_data->remote_surface.regions =
266 eina_list_remove_list(ec->comp_data->remote_surface.regions,
267 ec->comp_data->remote_surface.regions);
271 _remote_provider_onscreen_parent_set(E_Comp_Wl_Remote_Provider *provider, E_Comp_Wl_Remote_Surface *parent)
273 E_Comp_Wl_Remote_Region *region;
276 if (!provider) return;
277 if ((parent) && !(parent->ec)) return;
278 if (provider->onscreen_parent == parent) return;
280 _remote_provider_rect_clear(provider);
282 provider->onscreen_parent = parent;
283 provider->common.ec->comp_data->remote_surface.onscreen_parent = NULL;
285 RSMDBG("set onscreen_parent %p(ec:%p)",
286 provider->common.ec, "PROVIDER", provider,
287 parent, parent? parent->ec:NULL);
291 EINA_LIST_FOREACH(provider->onscreen_parent->regions, l, region)
293 _remote_provider_rect_add(provider, ®ion->geometry);
296 provider->common.ec->comp_data->remote_surface.onscreen_parent = parent->ec;
301 _remote_provider_onscreen_parent_calculate(E_Comp_Wl_Remote_Provider *provider)
305 E_Comp_Wl_Remote_Surface *surface, *parent = NULL;
309 if (!provider) return;
311 ec = provider->common.ec;
313 if (!ec->comp_data) return;
314 zone = e_comp_zone_find_by_ec(ec);
316 if (!provider->common.surfaces) return;
318 o = evas_object_top_get(e_comp->evas);
319 for (; o; o = evas_object_below_get(o))
321 _ec = evas_object_data_get(o, "E_Client");
323 if (_ec == ec) continue;
324 if (!_ec->remote_surface.consumer) continue;
325 if (e_object_is_del(E_OBJECT(_ec))) continue;
326 if (e_client_util_ignored_get(_ec)) continue;
327 if (!_ec->frame) continue;
328 if (!_ec->visible) continue;
329 if (_ec->visibility.skip) continue;
330 if ((_ec->visibility.obscured != E_VISIBILITY_UNOBSCURED) &&
331 (_ec->visibility.obscured != E_VISIBILITY_PARTIALLY_OBSCURED))
333 if (e_comp_wl_subsurface_check(_ec)) continue;
335 if (!e_zone_has_ec(zone, _ec)) continue;
336 if (!E_INTERSECTS(_ec->x, _ec->y, _ec->w, _ec->h, zone->x, zone->y, zone->w, zone->h))
339 EINA_LIST_FOREACH(provider->common.surfaces, l, surface)
341 if (_ec != surface->ec) continue;
342 if (!surface->visible) continue;
351 _remote_provider_onscreen_parent_set(provider, parent);
355 _remote_provider_offscreen_set(E_Comp_Wl_Remote_Provider* provider, Eina_Bool set)
359 EINA_SAFETY_ON_NULL_RETURN(provider);
360 EINA_SAFETY_ON_NULL_RETURN(provider->common.ec);
362 ec = provider->common.ec;
364 if (e_object_is_del(E_OBJECT(ec))) return;
368 provider->common.is_offscreen = set;
369 ec->ignored = EINA_TRUE;
371 //TODO: consider what happens if it's not normal client such as subsurface client
372 //TODO: save original values
373 if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.unmap))
375 ELOGF("COMP", "Call shell.unmap by rsm", ec);
376 e_client_shell_unmap(ec);
380 ec->visible = EINA_FALSE;
381 evas_object_hide(ec->frame);
382 ec->comp_data->mapped = 0;
385 ec->icccm.accepts_focus = ec->icccm.take_focus = ec->want_focus = EINA_FALSE;
386 ec->placed = EINA_TRUE;
387 e_client_visibility_skip_set(ec, EINA_TRUE);
389 _remote_provider_onscreen_parent_calculate(provider);
393 e_client_visibility_skip_set(ec, EINA_FALSE);
394 provider->common.is_offscreen = set;
395 ec->icccm.accepts_focus = ec->icccm.take_focus = ec->want_focus = EINA_TRUE;
396 ec->placed = EINA_FALSE;
398 _remote_provider_onscreen_parent_set(provider, NULL);
400 e_comp_wl_surface_commit(ec);
403 _remote_surface_ignore_output_transform_send(&provider->common);
405 RSMINF("%s offscreen", ec, "PROVIDER", provider, set? "Set":"Unset");
409 _remote_provider_visible_event_free(void *data EINA_UNUSED, E_Event_Remote_Surface_Provider *ev)
411 e_object_unref(E_OBJECT(ev->ec));
416 _remote_provider_visible_event_send(E_Comp_Wl_Remote_Provider *provider)
418 E_Event_Remote_Surface_Provider *ev;
420 if (e_object_is_del(E_OBJECT(provider->common.ec))) return;
422 ev = E_NEW(E_Event_Remote_Surface_Provider, 1);
425 ev->ec = provider->common.ec;
426 e_object_ref(E_OBJECT(provider->common.ec));
427 ecore_event_add(E_EVENT_REMOTE_SURFACE_PROVIDER_VISIBILITY_CHANGE, ev, (Ecore_End_Cb)_remote_provider_visible_event_free, NULL);
431 _remote_provider_visible_set(E_Comp_Wl_Remote_Provider *provider, Eina_Bool set)
433 EINA_SAFETY_ON_NULL_RETURN(provider);
437 provider->vis_ref ++;
438 RSMDBG("Count up vis_ref:%d", provider->common.ec,
439 "PROVIDER", provider, provider->vis_ref);
441 if (provider->vis_ref == 1)
443 provider->common.ec->visibility.obscured = E_VISIBILITY_UNOBSCURED;
445 _remote_provider_visible_event_send(provider);
446 e_policy_client_visibility_send(provider->common.ec);
448 tizen_remote_surface_provider_send_visibility
450 TIZEN_REMOTE_SURFACE_PROVIDER_VISIBILITY_TYPE_VISIBLE);
452 if (provider->buffer_mode)
453 e_pixmap_buffer_clear_cancel(provider->common.ec->pixmap);
458 provider->vis_ref --;
459 RSMDBG("Count down vis_ref:%d", provider->common.ec,
460 "PROVIDER", provider, provider->vis_ref);
462 if (provider->vis_ref == 0)
464 provider->common.ec->visibility.obscured = E_VISIBILITY_FULLY_OBSCURED;
466 _remote_provider_visible_event_send(provider);
467 e_policy_client_visibility_send(provider->common.ec);
469 tizen_remote_surface_provider_send_visibility
471 TIZEN_REMOTE_SURFACE_PROVIDER_VISIBILITY_TYPE_INVISIBLE);
473 if (provider->buffer_mode)
474 e_pixmap_buffer_clear(provider->common.ec->pixmap, EINA_TRUE);
478 _remote_provider_onscreen_parent_calculate(provider);
482 _remote_provider_client_set(E_Client *ec, Eina_Bool set)
485 if ((e_object_is_del(E_OBJECT(ec)))) return;
487 ec->remote_surface.provider = set;
490 static E_Comp_Wl_Remote_Provider *
491 _remote_provider_find(E_Client *ec)
493 E_Comp_Wl_Remote_Provider *provider;
495 EINA_SAFETY_ON_NULL_RETURN_VAL(_rsm, NULL);
496 EINA_SAFETY_ON_NULL_RETURN_VAL(_rsm->provider_hash, NULL);
498 provider = eina_hash_find(_rsm->provider_hash, &ec);
502 static E_Comp_Wl_Buffer *
503 _remote_surface_comp_wl_buffer_get(E_Client *ec)
505 E_Comp_Wl_Client_Data *cdata = NULL;
507 if (!ec) return NULL;
509 cdata = ec->comp_data;
510 if (!cdata) return NULL;
512 return cdata->buffer_ref.buffer;
516 _remote_surface_get_tbm_surface_from_ns(E_Client *ec)
519 Evas_Native_Surface *ns;
520 tbm_surface_h tbm_surface;
522 if (!ec) return NULL;
524 cobj = evas_object_name_child_find(ec->frame, "cw->obj", -1);
525 if (!cobj) return NULL;
527 ns = evas_object_image_native_surface_get(cobj);
528 if (!ns) return NULL;
529 if (ns->type != EVAS_NATIVE_SURFACE_TBM) return NULL;
531 tbm_surface = ns->data.tbm.buffer;
536 /* true : given buffer type can be delivered to the client
537 * false: the client wants to filter given buffer type, thus changed_buffer
538 * event for this type of buffer will not be sent to the client.
541 _remote_surface_changed_buff_ev_filter_check(E_Comp_Wl_Remote_Surface *rs,
542 enum tizen_remote_surface_buffer_type buff_type)
544 Eina_Bool res = EINA_TRUE;
546 if (rs->changed_buff_ev_filter.use)
550 case TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM:
551 if (rs->changed_buff_ev_filter.filter & TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_TBM)
554 case TIZEN_REMOTE_SURFACE_BUFFER_TYPE_IMAGE_FILE:
555 if (rs->changed_buff_ev_filter.filter & TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_IMAGE_FILE)
567 _remote_surface_changed_buff_protocol_send(E_Comp_Wl_Remote_Surface *rs,
568 enum tizen_remote_surface_buffer_type buff_type,
570 unsigned int img_file_size,
572 E_Comp_Wl_Buffer *buff,
573 tbm_surface_h tbm_surface,
576 E_Client *src_ec = NULL;
577 struct wl_resource *tbm = NULL;
578 Eina_Bool send = EINA_FALSE;
579 struct wl_array opts;
580 Eina_Bool add_opts = EINA_FALSE;
583 enum wl_output_transform output_transform;
587 src_ec = rs->provider->common.ec;
591 src_ec = rs->source->common.ec;
596 RSMINF("CHANGED_BUFF: no src_ec", NULL, "SURFACE", rs);
600 RSMDBG("CHANGED_BUFF: src_ec(%p) bind_ec(%p) buffer_transform(%d)",
601 rs->ec, "SURFACE", rs, src_ec, rs->bind_ec, e_comp_wl_output_buffer_transform_get(src_ec));
603 /* if unbinded, buffer_transform should be 0 for consumer to composite buffers.
604 * Otherwise, we skip sending a change_buffer event because buffer is not ready.
607 output_transform = e_comp_wl_output_pending_buffer_transform_get(src_ec);
609 output_transform = e_comp_wl_output_buffer_transform_get(src_ec);
611 if (!rs->bind_ec && output_transform)
613 RSMINF("CHANGED_BUFF skiped: buffer not ready", rs->ec, "SURFACE", rs);
617 send = _remote_surface_changed_buff_ev_filter_check(rs, buff_type);
620 if (buff_type == TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM)
622 struct wl_resource *rbuff_res = NULL;
623 E_Comp_Wl_Remote_Buffer *rbuff = NULL;
625 EINA_SAFETY_ON_FALSE_RETURN_VAL((buff) || (tbm_surface), EINA_FALSE);
627 //try to get remote buffer from wl_buffer resource
629 rbuff_res = e_comp_wl_tbm_remote_buffer_get(rs->wl_tbm, buff->resource);
635 //try to get remote buffer from tbm surface
636 rbuff_res = e_comp_wl_tbm_remote_buffer_get_with_tbm(rs->wl_tbm, tbm_surface);
639 EINA_SAFETY_ON_NULL_RETURN_VAL(rbuff_res, EINA_FALSE);
641 rbuff = _e_comp_wl_remote_buffer_get(rs, rbuff_res);
642 EINA_SAFETY_ON_NULL_RETURN_VAL(rbuff, EINA_FALSE);
644 tbm = rbuff->resource;
645 EINA_SAFETY_ON_NULL_RETURN_VAL(tbm, EINA_FALSE);
647 if ((buff) && (ref_set) &&
648 (rs->version >= 2)) /* WORKAROUND for 3.0: old version wayland-scanner can't generation since macro. TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION */
649 e_comp_wl_buffer_reference(&rbuff->ref, buff);
652 if (rs->version >= TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION)
654 if (rs->req_curr_buff.set)
656 /* example of option list:
657 * [0] "curr_buff_req_serial"
661 wl_array_init(&opts);
662 p = wl_array_add(&opts, 21);
663 if (p) strncpy(p, "curr_buff_req_serial", 21);
665 snprintf(tmp, sizeof(tmp), "%u", rs->req_curr_buff.serial);
666 len = strlen(tmp) + 1;
667 p = wl_array_add(&opts, len);
668 if (p) strncpy(p, tmp, len);
670 p = wl_array_add(&opts, 9);
671 if (p) strncpy(p, "opt_none", 9);
673 rs->req_curr_buff.set = EINA_FALSE;
674 add_opts = EINA_TRUE;
677 RSMDBG("CHANGED_BUFF send:%d type:%u tbm:%p fd:%d(%d) add_opts:%d EV_FILTER(%d):%u",
678 rs->ec, "SURFACE", rs,
679 send, buff_type, tbm, img_file_fd, img_file_size, add_opts,
680 rs->changed_buff_ev_filter.use,
681 rs->changed_buff_ev_filter.filter);
683 tizen_remote_surface_send_changed_buffer(rs->resource,
688 e_util_timestamp_get(),
689 add_opts ? &opts : NULL);
692 tizen_remote_surface_send_update_buffer(rs->resource,
694 e_util_timestamp_get());
698 wl_array_release(&opts);
704 _remote_surface_buff_send(E_Comp_Wl_Remote_Surface *rs)
706 enum tizen_remote_surface_buffer_type buff_type;
707 E_Comp_Wl_Remote_Provider *provider;
708 E_Comp_Wl_Remote_Source *source;
709 E_Client *src_ec = NULL;
711 E_Comp_Wl_Buffer *buff = NULL;
712 tbm_surface_h tbm_surface = NULL;
715 int fd = _rsm->dummy_fd;
718 Eina_Bool res = EINA_FALSE;
721 provider = rs->provider;
725 src_ec = provider->common.ec;
730 src_ec = source->common.ec;
731 img_path = (char *)source->image_path;
734 EINA_SAFETY_ON_NULL_RETURN_VAL(src_ec, EINA_FALSE);
736 buff = _remote_surface_comp_wl_buffer_get(src_ec);
737 tbm_surface = _remote_surface_get_tbm_surface_from_ns(src_ec);
739 if ((buff) || (tbm_surface))
741 buff_type = TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM;
744 /* TODO: if client wants to receive image file for the remote_surfac_provider,
745 * then makes image file from tbm buffer and sends information for that file.
746 * otherwise, just sends tbm buffer to the client.
748 res = _remote_surface_changed_buff_protocol_send(rs,
751 (unsigned int)img_size,
753 buff, tbm_surface, EINA_FALSE);
757 EINA_SAFETY_ON_NULL_RETURN_VAL(img_path, EINA_FALSE);
759 fd = open(img_path, O_RDONLY);
760 EINA_SAFETY_ON_FALSE_RETURN_VAL(fd != -1, EINA_FALSE);
762 img_size = lseek(fd, 0, SEEK_END);
763 EINA_SAFETY_ON_FALSE_GOTO(img_size > 0, close_fd);
765 buff_type = TIZEN_REMOTE_SURFACE_BUFFER_TYPE_IMAGE_FILE;
768 /* TODO: if client wants to receive image file for the remote_surfac_provider,
769 * then makes image file from tbm buffer and sends information for that file.
770 * otherwise, just sends tbm buffer to the client.
772 res = _remote_surface_changed_buff_protocol_send(rs,
775 (unsigned int)img_size,
777 NULL, NULL, EINA_FALSE);
790 _remote_surface_visible_set(E_Comp_Wl_Remote_Surface *remote_surface, Eina_Bool set)
792 E_Comp_Wl_Remote_Provider *provider;
794 if (remote_surface->visible == set) return;
796 remote_surface->visible = set;
798 RSMDBG("Switch visible:%d",
799 remote_surface->ec, "SURFACE", remote_surface, remote_surface->visible);
801 provider = remote_surface->provider;
802 if (!provider) return;
804 _remote_provider_visible_set(provider, set);
808 _remote_surface_cb_effect_end(void *data, E_Client *ec)
810 E_Comp_Wl_Remote_Surface *remote_surface;
811 Eina_List *surfaces, *l;
814 if (!_rsm) return EINA_TRUE;
815 if (!ec) return EINA_TRUE;
817 surfaces = eina_hash_find(_rsm->consumer_hash, &ec);
818 if (!surfaces) return EINA_TRUE;
820 EINA_LIST_FOREACH(surfaces, l, remote_surface)
822 if (!remote_surface->bind_ec) continue;
823 if (!remote_surface->need_prebind) continue;
825 bind_ec = remote_surface->bind_ec;
827 RSMINF("Send \"prebind\" bind_ec:%p", remote_surface->ec,
828 "SURFACE", remote_surface, bind_ec);
830 e_policy_aux_message_send(bind_ec, "tz_remote_surface_mng", "prebind", NULL);
831 remote_surface->need_prebind = EINA_FALSE;
833 _rsm->wait_effect_end --;
836 if (!_rsm->wait_effect_end)
838 e_comp_object_hook_del(_rsm->effect_end);
839 _rsm->effect_end = NULL;
846 _remote_surface_prebind_send(E_Comp_Wl_Remote_Surface *remote_surface)
848 E_Client *bind_ec, *consumer_ec;
850 if (!remote_surface) return;
851 if (!remote_surface->bind_ec) return;
852 if (!remote_surface->need_prebind) return;
854 bind_ec = remote_surface->bind_ec;
855 consumer_ec = remote_surface->ec;
857 //object visibility of bind_ec
858 if (!evas_object_visible_get(bind_ec->frame)) return;
860 //check wether effect of consumer_ec is running
861 if ((consumer_ec) && (evas_object_data_get(consumer_ec->frame, "effect_running")))
863 RSMINF("Sending \"prebind\" is pending until EFFECT_END bind_ec(%p)",
865 "SURFACE", remote_surface, remote_surface->bind_ec);
867 _rsm->wait_effect_end ++;
868 if (_rsm->effect_end) return;
869 _rsm->effect_end = e_comp_object_hook_add(E_COMP_OBJECT_HOOK_EFFECT_END,
870 _remote_surface_cb_effect_end,
875 RSMINF("Send \"prebind\" bind_ec:%p",
877 "SURFACE", remote_surface, remote_surface->bind_ec);
879 e_policy_aux_message_send(remote_surface->bind_ec, "tz_remote_surface_mng", "prebind", NULL);
880 remote_surface->need_prebind = EINA_FALSE;
885 _remote_surface_bind_client_set(E_Comp_Wl_Remote_Surface *remote_surface, E_Client *ec)
887 if (!remote_surface) return;
889 RSMINF("Set bind_ec:%p, bind_ref:%d",
890 remote_surface->ec, "SURFACE", remote_surface, ec, ec->remote_surface.bind_ref + 1);
892 remote_surface->bind_ec = ec;
893 remote_surface->bind_ec->remote_surface.bind_ref++;
897 _remote_surface_bind_client_unset(E_Comp_Wl_Remote_Surface *remote_surface)
899 if (!remote_surface) return;
901 RSMINF("Unset bind_ec:%p, bind_ref:%d",
903 "SURFACE", remote_surface, remote_surface->bind_ec,
904 remote_surface->bind_ec->remote_surface.bind_ref - 1);
906 remote_surface->bind_ec->remote_surface.bind_ref--;
907 remote_surface->bind_ec = NULL;
911 _remote_surface_bind_client(E_Comp_Wl_Remote_Surface *remote_surface, E_Client *ec)
913 if (!remote_surface) return;
914 if ((ec) && (remote_surface->bind_ec == ec)) return;
916 /* clear previous binding */
917 if (remote_surface->bind_ec)
919 RSMINF("Clear previous bind_ec:%p",
920 remote_surface->ec, "SURFACE", remote_surface, remote_surface->bind_ec);
922 /* check the base_output resolution */
923 if (remote_surface->provider && remote_surface->provider->common.ec)
924 e_client_base_output_resolution_rsm_update(remote_surface->bind_ec, remote_surface->provider->common.ec);
926 remote_surface->bind_ec->comp_data->pending.sx = 0;
927 remote_surface->bind_ec->comp_data->pending.sy = 0;
928 remote_surface->bind_ec->comp_data->pending.new_attach = EINA_TRUE;
930 e_comp_wl_surface_attach(remote_surface->bind_ec, NULL);
931 e_comp_object_render_update_del(remote_surface->bind_ec->frame);
933 eina_hash_del(_rsm->bind_surface_hash, &remote_surface->bind_ec, remote_surface);
934 remote_surface->need_prebind = EINA_FALSE;
935 _remote_surface_bind_client_unset(remote_surface);
937 /* try to send latest buffer of the provider to the consumer when unbinding
938 * the remote surface to avoid showing old buffer on consumer's window for a while.
940 if (remote_surface->provider)
942 E_Comp_Wl_Buffer *buffer;
944 RSMINF("Try to send latest buffer of provider:%p(ec:%p)",
945 remote_surface->ec, "SURFACE", remote_surface,
946 remote_surface->provider,
947 remote_surface->provider->common.ec);
949 EINA_SAFETY_ON_NULL_GOTO(remote_surface->provider->common.ec, bind_ec_set);
951 buffer = _remote_surface_comp_wl_buffer_get(remote_surface->provider->common.ec);
952 EINA_SAFETY_ON_NULL_GOTO(buffer, bind_ec_set);
954 _remote_surface_changed_buff_protocol_send(remote_surface,
955 TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM,
959 buffer, NULL, EINA_FALSE);
966 if (e_object_is_del(E_OBJECT(ec)))
968 ERR("Trying to bind with deleted EC(%p)", ec);
972 /* TODO: enable user geometry? */
973 e_policy_user_geometry_set(ec, E_POLICY_USERGEOM_RSM, EINA_TRUE);
974 _remote_surface_bind_client_set(remote_surface, ec);
975 eina_hash_add(_rsm->bind_surface_hash, &remote_surface->bind_ec, remote_surface);
977 /* try to set latest buffer of the provider to bind_ec */
978 if (remote_surface->provider && remote_surface->provider->common.ec)
980 E_Comp_Wl_Buffer *buffer;
982 buffer = _remote_surface_comp_wl_buffer_get(remote_surface->provider->common.ec);
983 EINA_SAFETY_ON_NULL_RETURN(buffer);
985 _e_comp_wl_remote_surface_state_buffer_set(&remote_surface->bind_ec->comp_data->pending, buffer);
987 remote_surface->bind_ec->comp_data->pending.sx = 0;
988 remote_surface->bind_ec->comp_data->pending.sy = 0;
989 remote_surface->bind_ec->comp_data->pending.new_attach = EINA_TRUE;
991 remote_surface->bind_ec->comp_data->pending.buffer_viewport =
992 remote_surface->provider->common.ec->comp_data->scaler.buffer_viewport;
994 /* check the base_output resolution */
995 e_client_base_output_resolution_rsm_update(ec, remote_surface->provider->common.ec);
997 e_comp_wl_surface_commit(remote_surface->bind_ec);
999 remote_surface->need_prebind = EINA_TRUE;
1000 _remote_surface_prebind_send(remote_surface);
1002 e_comp_render_queue();
1008 _remote_surface_ignore_output_transform_send(E_Comp_Wl_Remote_Common *common)
1010 E_Comp_Wl_Remote_Surface *remote_surface;
1013 Eina_Bool bind = EINA_FALSE;
1015 EINA_SAFETY_ON_NULL_RETURN(common);
1017 EINA_LIST_FOREACH(common->surfaces, l, remote_surface)
1019 if (!remote_surface) continue;
1021 if (remote_surface->bind_ec)
1024 if (remote_surface->redirect && !remote_surface->bind_ec)
1026 msg = "remote surface redirect and not bind";
1033 msg = "remote surface bind";
1037 if (common->is_offscreen)
1044 msg = "not offscreen";
1049 if (common->ignore_output_transform != EINA_TRUE)
1051 ELOGF("TRANSFORM", "ignore output transform: %s", common->ec, msg);
1052 e_comp_screen_rotation_ignore_output_transform_send(common->ec, EINA_TRUE);
1053 common->ignore_output_transform = EINA_TRUE;
1058 if (common->ignore_output_transform != EINA_FALSE)
1060 ELOGF("TRANSFORM", "not ignore output transform: %s", common->ec, msg);
1061 e_comp_screen_rotation_ignore_output_transform_send(common->ec, EINA_FALSE);
1062 common->ignore_output_transform = EINA_FALSE;
1068 _remote_surface_region_clear(E_Comp_Wl_Remote_Surface *remote_surface)
1071 E_Comp_Wl_Remote_Region *region;
1072 if (!remote_surface) return;
1074 EINA_LIST_FOREACH(remote_surface->regions, l, region)
1076 _remote_region_mirror_clear(region);
1081 _remote_surface_client_set(E_Client *ec, Eina_Bool set)
1084 if ((e_object_is_del(E_OBJECT(ec)))) return;
1086 ec->remote_surface.consumer = set;
1090 _remote_source_send_image_update(E_Comp_Wl_Remote_Source *source)
1095 E_Comp_Wl_Remote_Surface *remote_surface;
1097 if (!source->image_path) return;
1099 fd = open(source->image_path, O_RDONLY);
1106 image_size = lseek(fd, 0, SEEK_END);
1107 if (image_size <= 0)
1113 RSMDBG("send image fd(%d) path(%s) size(%jd)",
1114 source->common.ec, "SOURCE", source, fd, source->image_path, (intmax_t)image_size);
1116 EINA_LIST_FOREACH(source->common.surfaces, l, remote_surface)
1118 if (remote_surface->version < TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION)
1121 _remote_surface_changed_buff_protocol_send(remote_surface,
1122 TIZEN_REMOTE_SURFACE_BUFFER_TYPE_IMAGE_FILE,
1124 (unsigned int)image_size,
1126 NULL, NULL, EINA_FALSE);
1132 static E_Comp_Wl_Remote_Source *
1133 _remote_source_find(E_Client *ec)
1135 E_Comp_Wl_Remote_Source *source;
1137 EINA_SAFETY_ON_NULL_RETURN_VAL(_rsm, NULL);
1138 EINA_SAFETY_ON_NULL_RETURN_VAL(_rsm->source_hash, NULL);
1140 source = eina_hash_find(_rsm->source_hash, &ec);
1144 static E_Comp_Wl_Remote_Source *
1145 _remote_source_get(E_Client *ec)
1147 E_Comp_Wl_Remote_Source *source = NULL;
1149 source = _remote_source_find(ec);
1152 if (e_object_is_del(E_OBJECT(ec)))
1155 source = E_NEW(E_Comp_Wl_Remote_Source, 1);
1156 if (!source) return NULL;
1158 source->common.ec = ec;
1159 eina_hash_add(_rsm->source_hash, &ec, source);
1166 _remote_source_destroy(E_Comp_Wl_Remote_Source *source)
1168 E_Comp_Wl_Remote_Surface *remote_surface;
1169 if (!source) return;
1171 RSMDBG("remote source destroy", source->common.ec,"SOURCE", source);
1174 eina_hash_del_by_data(_rsm->source_hash, source);
1176 EINA_LIST_FREE(source->common.surfaces, remote_surface)
1178 if (remote_surface->source == source)
1180 remote_surface->source = NULL;
1181 tizen_remote_surface_send_missing(remote_surface->resource);
1185 /* is it ok without client's ack ?*/
1186 if (source->image_path)
1188 if (!e_config->hold_prev_win_img)
1190 RSMDBG("IMG del %s", source->common.ec, "SOURCE", source, source->image_path);
1191 ecore_file_remove(source->image_path);
1193 eina_stringshare_del(source->image_path);
1200 _remote_source_default_path_get(E_Client *ec, Eina_Stringshare** dir, Eina_Stringshare** fname)
1203 char dest_dir[1024];
1204 char dest[PATH_MAX];
1210 run_dir = e_util_env_get("XDG_RUNTIME_DIR");
1211 if (!run_dir) return;
1213 snprintf(dest_dir, sizeof(dest_dir), "%s/.e-img", run_dir);
1216 if (!ecore_file_exists(dest_dir))
1217 ecore_file_mkdir(dest_dir);
1219 snprintf(name, sizeof(name),
1222 e_pixmap_res_id_get(ec->pixmap), id);
1224 snprintf(dest, sizeof(dest), "%s/%s.png", dest_dir, name);
1225 while (ecore_file_exists(dest))
1227 snprintf(name, sizeof(name),
1230 e_pixmap_res_id_get(ec->pixmap), ++id);
1231 snprintf(dest, sizeof(dest), "%s/%s.png", dest_dir, name);
1234 *dir = eina_stringshare_add(dest_dir);
1235 *fname = eina_stringshare_add(name);
1239 _remote_source_offscreen_set(E_Comp_Wl_Remote_Source *source, Eina_Bool set)
1241 EINA_SAFETY_ON_NULL_RETURN(source);
1244 source->offscreen_ref++;
1245 RSMDBG("Set offscreen offscreen_ref:%d",
1246 source->common.ec, "SOURCE", source, source->offscreen_ref);
1248 if (source->offscreen_ref == 1)
1250 source->common.is_offscreen = EINA_TRUE;
1251 _remote_surface_ignore_output_transform_send(&source->common);
1253 source->common.ec->exp_iconify.not_raise = 1;
1254 if (!e_client_is_iconified_by_client(source->common.ec))
1255 e_policy_wl_iconify_state_change_send(source->common.ec, 0);
1257 RSMINF("Un-Set ICONIFY BY Remote_Surface", source->common.ec,
1259 e_client_uniconify(source->common.ec);
1261 source->common.ec->exp_iconify.by_client = 0;
1262 e_client_iconified_type_set(source->common.ec, E_ICONIFIED_TYPE_NONE);
1263 source->common.ec->exp_iconify.skip_by_remote = 1;
1265 EC_CHANGED(source->common.ec);
1270 if (!source->common.is_offscreen)
1273 source->offscreen_ref--;
1274 RSMDBG("Unset offscreen offscreen_ref:%d",
1275 source->common.ec, "SOURCE", source, source->offscreen_ref);
1277 if (source->offscreen_ref == 0)
1279 source->common.is_offscreen = EINA_FALSE;
1280 _remote_surface_ignore_output_transform_send(&source->common);
1281 source->common.ec->exp_iconify.skip_by_remote = 0;
1282 EC_CHANGED(source->common.ec);
1288 _remote_region_cb_mirror_del(void *data, Evas *e, Evas_Object *obj, void *event_info)
1290 E_Comp_Wl_Remote_Region *region = data;
1291 if (!region->mirror) return;
1293 region->mirror = NULL;
1297 _remote_region_cb_resource_destroy(struct wl_resource *resource)
1299 E_Comp_Wl_Remote_Region *region;
1301 region = wl_resource_get_user_data(resource);
1302 if (!region) return;
1304 if (region->remote_surface)
1306 if (region->remote_surface->provider)
1308 _remote_provider_rect_del(region->remote_surface->provider,
1311 region->remote_surface->regions = eina_list_remove(region->remote_surface->regions,
1317 evas_object_event_callback_del_full(region->mirror, EVAS_CALLBACK_DEL, _remote_region_cb_mirror_del, region);
1318 evas_object_del(region->mirror);
1325 _remote_region_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
1327 wl_resource_destroy(resource);
1331 _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)
1333 E_Comp_Wl_Remote_Region *region;
1335 region = wl_resource_get_user_data(resource);
1336 if (!region) return;
1338 region->geometry.x = x;
1339 region->geometry.y = y;
1340 region->geometry.w = w;
1341 region->geometry.h = h;
1343 RSMDBG("Region %p geometry set (%d, %d) %dx%d",
1344 NULL, "SURFACE", region->remote_surface, region, x, y, w, h);
1347 static const struct tizen_remote_surface_region_interface _remote_region_interface =
1349 _remote_region_cb_destroy,
1350 _remote_region_cb_geometry_set,
1354 _remote_provider_cb_resource_destroy(struct wl_resource *resource)
1356 E_Comp_Wl_Remote_Provider *provider;
1357 E_Comp_Wl_Remote_Surface *remote_surface;
1359 provider = wl_resource_get_user_data(resource);
1360 if (!provider) return;
1363 eina_hash_del(_rsm->provider_hash, &provider->common.ec, provider);
1365 EINA_LIST_FREE(provider->common.surfaces, remote_surface)
1367 if (remote_surface->provider == provider)
1369 /* unset remote buffer from provider */
1370 if (remote_surface->bind_ec)
1371 _remote_surface_bind_client(remote_surface, NULL);
1373 remote_surface->provider = NULL;
1374 //notify of this ejection to remote surface_resource
1375 tizen_remote_surface_send_missing(remote_surface->resource);
1379 _remote_provider_client_set(provider->common.ec, EINA_FALSE);
1384 _remote_provider_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
1386 wl_resource_destroy(resource);
1390 _remote_provider_cb_offscreen_set(struct wl_client *client EINA_UNUSED, struct wl_resource *provider_resource, uint32_t offscreen)
1392 E_Comp_Wl_Remote_Provider *provider;
1394 provider = wl_resource_get_user_data(provider_resource);
1395 if (!provider) return;
1397 if (provider->common.is_offscreen == offscreen) return;
1398 _remote_provider_offscreen_set(provider, offscreen);
1402 _remote_provider_cb_input_event_filter_set(struct wl_client *client EINA_UNUSED, struct wl_resource *provider_resource, uint32_t event_filter)
1404 E_Comp_Wl_Remote_Provider *provider;
1405 E_Comp_Wl_Remote_Surface *remote_surface;
1408 provider = wl_resource_get_user_data(provider_resource);
1409 if (!provider) return;
1411 provider->input_event_filter = event_filter;
1412 RSMDBG("set input event filter 0x%08x",
1413 provider->common.ec, "PROVIDER", provider, event_filter);
1415 if (!event_filter) return;
1417 EINA_LIST_FOREACH(provider->common.surfaces, l, remote_surface)
1419 if (remote_surface->version >= TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_SINCE_VERSION)
1420 tizen_remote_surface_send_input_event_filter(remote_surface->resource, event_filter);
1424 static const struct tizen_remote_surface_provider_interface _remote_provider_interface =
1426 _remote_provider_cb_destroy,
1427 _remote_provider_cb_offscreen_set,
1428 _remote_provider_cb_input_event_filter_set,
1432 _remote_surface_cb_tbm_destroy(struct wl_listener *listener, void *data)
1434 E_Comp_Wl_Remote_Surface *remote_surface;
1436 remote_surface = container_of(listener, E_Comp_Wl_Remote_Surface, tbm_destroy_listener);
1437 if (!remote_surface) return;
1439 if (remote_surface->tbm_destroy_listener.notify)
1441 wl_list_remove(&remote_surface->tbm_destroy_listener.link);
1442 remote_surface->tbm_destroy_listener.notify = NULL;
1445 remote_surface->wl_tbm = NULL;
1449 _remote_surface_cb_resource_destroy(struct wl_resource *resource)
1451 E_Comp_Wl_Remote_Surface *remote_surface;
1452 E_Comp_Wl_Remote_Provider *provider;
1453 E_Comp_Wl_Remote_Source *source;
1454 E_Comp_Wl_Remote_Region *region;
1455 E_Comp_Wl_Remote_Buffer *remote_buf;
1457 remote_surface = wl_resource_get_user_data(resource);
1458 if (!remote_surface) return;
1460 provider = remote_surface->provider;
1463 _remote_surface_visible_set(remote_surface, EINA_FALSE);
1464 if (provider->onscreen_parent == remote_surface)
1465 _remote_provider_onscreen_parent_set(provider, NULL);
1467 provider->common.surfaces = eina_list_remove(provider->common.surfaces,
1469 remote_surface->provider = NULL;
1472 source = remote_surface->source;
1475 source->common.surfaces = eina_list_remove(source->common.surfaces, remote_surface);
1476 remote_surface->source = NULL;
1479 EINA_LIST_FREE(remote_surface->regions, region)
1481 region->remote_surface = NULL;
1482 wl_resource_destroy(region->resource);
1485 EINA_LIST_FREE(remote_surface->send_remote_bufs, remote_buf)
1487 remote_buf->remote_surface = NULL;
1488 wayland_tbm_server_send_destroy_buffer(remote_surface->wl_tbm, remote_buf->resource);
1491 if (remote_surface->bind_ec)
1492 _remote_surface_bind_client(remote_surface, NULL);
1493 if (remote_surface->ec)
1495 Eina_List *surfaces;
1497 surfaces = eina_hash_find(_rsm->consumer_hash, &remote_surface->ec);
1500 eina_hash_del_by_key(_rsm->consumer_hash, &remote_surface->ec);
1501 surfaces = eina_list_remove(surfaces, remote_surface);
1503 _remote_surface_client_set(remote_surface->ec, EINA_FALSE);
1505 eina_hash_add(_rsm->consumer_hash, &remote_surface->ec, surfaces);
1509 if (remote_surface->wl_tbm)
1510 wl_list_remove(&remote_surface->tbm_destroy_listener.link);
1513 _remote_surface_ignore_output_transform_send(&provider->common);
1515 _remote_surface_ignore_output_transform_send(&source->common);
1517 E_FREE(remote_surface);
1521 _remote_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
1523 wl_resource_destroy(resource);
1527 _remote_surface_cb_redirect(struct wl_client *client, struct wl_resource *resource)
1529 E_Comp_Wl_Buffer *buffer;
1530 E_Comp_Wl_Remote_Surface *remote_surface;
1531 tbm_surface_h tbm_surface;
1533 EINA_SAFETY_ON_NULL_RETURN(_rsm);
1535 remote_surface = wl_resource_get_user_data(resource);
1536 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
1537 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
1539 if (remote_surface->provider)
1541 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider->common.ec);
1543 if (remote_surface->redirect)
1545 RSMINF("Already Redirect surface provider:%p(ec:%p)",
1546 remote_surface->ec, "SURFACE", remote_surface,
1547 remote_surface->provider, remote_surface->provider->common.ec);
1551 RSMINF("Redirect surface provider:%p(ec:%p)",
1552 remote_surface->ec, "SURFACE", remote_surface,
1553 remote_surface->provider, remote_surface->provider->common.ec);
1555 remote_surface->redirect = EINA_TRUE;
1556 _remote_surface_ignore_output_transform_send(&remote_surface->provider->common);
1558 /* Send input event filter of provider */
1559 if ((remote_surface->provider->input_event_filter) &&
1560 (remote_surface->version >= TIZEN_REMOTE_SURFACE_INPUT_EVENT_FILTER_SINCE_VERSION))
1561 tizen_remote_surface_send_input_event_filter(resource,
1562 remote_surface->provider->input_event_filter);
1564 buffer = _remote_surface_comp_wl_buffer_get(remote_surface->provider->common.ec);
1565 tbm_surface = _remote_surface_get_tbm_surface_from_ns(remote_surface->provider->common.ec);
1566 EINA_SAFETY_ON_FALSE_RETURN((buffer) || (tbm_surface));
1568 _remote_surface_changed_buff_protocol_send(remote_surface,
1569 TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM,
1573 buffer, tbm_surface, EINA_FALSE);
1575 else if (remote_surface->source)
1577 EINA_SAFETY_ON_NULL_RETURN(remote_surface->source->common.ec);
1579 if (remote_surface->redirect)
1581 RSMINF("Already Redirect surface source:%p(ec:%p)",
1582 remote_surface->ec, "SURFACE", remote_surface,
1583 remote_surface->source, remote_surface->source->common.ec);
1588 RSMINF("Redirect surface source:%p(ec:%p)",
1589 remote_surface->ec, "SURFACE", remote_surface,
1590 remote_surface->source, remote_surface->source->common.ec);
1592 if (remote_surface->version < TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION)
1595 remote_surface->redirect = EINA_TRUE;
1596 _remote_surface_ignore_output_transform_send(&remote_surface->source->common);
1598 buffer = _remote_surface_comp_wl_buffer_get(remote_surface->source->common.ec);
1599 tbm_surface = _remote_surface_get_tbm_surface_from_ns(remote_surface->source->common.ec);
1601 if ((buffer) || (tbm_surface))
1603 _remote_surface_changed_buff_protocol_send(remote_surface,
1604 TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM,
1608 buffer, tbm_surface, EINA_FALSE);
1612 _remote_source_send_image_update(remote_surface->source);
1618 _remote_surface_cb_unredirect(struct wl_client *client, struct wl_resource *resource)
1620 E_Comp_Wl_Remote_Surface *remote_surface;
1622 remote_surface = wl_resource_get_user_data(resource);
1623 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
1624 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
1626 remote_surface->redirect = EINA_FALSE;
1627 if (remote_surface->provider)
1628 _remote_surface_ignore_output_transform_send(&remote_surface->provider->common);
1629 else if (remote_surface->source)
1630 _remote_surface_ignore_output_transform_send(&remote_surface->source->common);
1632 RSMINF("Unredirect surface provider:%p(ec:%p)",
1633 remote_surface->ec, "SURFACE", remote_surface,
1634 remote_surface->provider, remote_surface->provider? remote_surface->provider->common.ec: NULL);
1638 _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)
1640 E_Comp_Wl_Remote_Provider *provider;
1641 E_Comp_Wl_Remote_Surface *remote_surface;
1644 Ecore_Device *edev = NULL;
1645 Ecore_Device_Class eclas = ECORE_DEVICE_CLASS_NONE;
1646 double eradx, erady, epressure, eangle;
1648 E_Comp_Config *comp_conf = NULL;
1651 remote_surface = wl_resource_get_user_data(resource);
1652 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
1653 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
1654 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider);
1655 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider->common.ec);
1657 provider = remote_surface->provider;
1658 ec = provider->common.ec;
1660 if (e_object_is_del(E_OBJECT(ec))) return;
1662 /* identify class */
1663 eclas = _device_class_convert_to_ecore(clas);
1664 if (eclas == ECORE_DEVICE_CLASS_NONE)
1666 ERR("Not supported device class(%d) subclass(%d) identifier(%s)",
1667 clas, subclas, identifier);
1670 /* find ecore device*/
1671 edev = _device_get_by_identifier(identifier, eclas);
1674 eradx = wl_fixed_to_double(radius_x);
1675 erady = wl_fixed_to_double(radius_y);
1676 epressure = wl_fixed_to_double(pressure);
1677 eangle = wl_fixed_to_double(angle);
1679 comp_conf = e_comp_config_get();
1680 if (comp_conf && comp_conf->input_log_enable)
1682 if (event_type != TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_MOVE)
1684 wl_client_get_credentials(client, &pid, NULL, NULL);
1685 ELOGF("TRS", "TRANSFER Mouse event [pid: %d -> pid: %d (ec: %p)] type: %d, time: %d",
1686 NULL, pid, ec?ec->netwm.pid:-1, ec, event_type, time);
1687 ELOGF("TRS", "\tDetail: device: %d, button: %d, x:%d, y:%d, clas: %d, identifier: %20s",
1688 NULL, device, button, x, y, clas, identifier);
1692 if (eclas == ECORE_DEVICE_CLASS_MOUSE)
1696 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_DOWN:
1697 e_client_mouse_button_send(ec,
1703 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_UP:
1704 e_client_mouse_button_send(ec,
1710 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_MOVE:
1711 e_client_mouse_move_send(ec,
1716 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_IN:
1717 e_client_mouse_in_send(ec,
1722 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_OUT:
1723 e_client_mouse_out_send(ec,
1728 ERR("Not supported event_type(%d)", event_type);
1732 else if (eclas == ECORE_DEVICE_CLASS_TOUCH)
1736 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_DOWN:
1737 /* FIXME: temporary fix for first touch down w/o move event */
1738 e_client_touch_update_send(ec,
1742 eradx, erady, epressure, eangle,
1744 e_client_touch_send(ec,
1749 eradx, erady, epressure, eangle,
1752 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_UP:
1753 e_client_touch_send(ec,
1758 eradx, erady, epressure, eangle,
1761 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_MOVE:
1762 e_client_touch_update_send(ec,
1766 eradx, erady, epressure, eangle,
1769 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_IN:
1770 e_client_mouse_in_send(ec,
1775 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_OUT:
1776 e_client_mouse_out_send(ec,
1781 ERR("Not supported event_type(%d)", event_type);
1788 _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)
1790 E_Comp_Wl_Remote_Provider *provider;
1791 E_Comp_Wl_Remote_Surface *remote_surface;
1794 Ecore_Device *edev = NULL;
1795 Ecore_Device_Class eclas = ECORE_DEVICE_CLASS_NONE;
1797 E_Comp_Config *comp_conf = NULL;
1800 remote_surface = wl_resource_get_user_data(resource);
1801 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
1802 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
1803 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider);
1804 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider->common.ec);
1806 provider = remote_surface->provider;
1807 ec = provider->common.ec;
1809 if (e_object_is_del(E_OBJECT(ec))) return;
1811 /* identify class */
1812 eclas = _device_class_convert_to_ecore(clas);
1813 if (eclas == ECORE_DEVICE_CLASS_NONE)
1815 ERR("Not supported device class(%d) subclass(%d) identifier(%s)",
1816 clas, subclas, identifier);
1818 edev = _device_get_by_identifier(identifier, eclas);
1820 comp_conf = e_comp_config_get();
1821 if (comp_conf && comp_conf->input_log_enable)
1823 wl_client_get_credentials(client, &pid, NULL, NULL);
1824 ELOGF("TRS", "TRANSFER Mouse wheel [pid: %d -> pid: %d (ec: %p)], time: %d",
1825 NULL, pid, ec?ec->netwm.pid:-1, ec, time);
1826 ELOGF("TRS", "\tDetail: direction: %d, z: %d, clas: %d, identifier: %20s)",
1827 NULL, direction, z, clas, identifier);
1830 e_client_mouse_wheel_send(ec, direction, z, edev, time);
1834 _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)
1836 E_Comp_Wl_Remote_Provider *provider;
1837 E_Comp_Wl_Remote_Surface *remote_surface;
1840 Ecore_Device *edev = NULL;
1841 Ecore_Device_Class eclas = ECORE_DEVICE_CLASS_NONE;
1842 double eradx, erady, epressure, eangle;
1844 E_Comp_Config *comp_conf = NULL;
1847 remote_surface = wl_resource_get_user_data(resource);
1848 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
1849 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
1850 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider);
1851 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider->common.ec);
1853 provider = remote_surface->provider;
1854 ec = provider->common.ec;
1856 if (e_object_is_del(E_OBJECT(ec))) return;
1858 /* identify class */
1859 if (clas == TIZEN_INPUT_DEVICE_CLAS_TOUCHSCREEN)
1860 eclas = ECORE_DEVICE_CLASS_TOUCH;
1863 ERR("Not supported device clas(%d) subclas(%d identifier(%s)",
1864 clas, subclas, identifier);
1868 /* identify class */
1869 eclas = _device_class_convert_to_ecore(clas);
1870 if (eclas == ECORE_DEVICE_CLASS_NONE)
1872 ERR("Not supported device class(%d) subclass(%d) identifier(%s)",
1873 clas, subclas, identifier);
1876 /* find ecore device*/
1877 edev = _device_get_by_identifier(identifier, eclas);
1880 eradx = wl_fixed_to_double(radius_x);
1881 erady = wl_fixed_to_double(radius_y);
1882 epressure = wl_fixed_to_double(pressure);
1883 eangle = wl_fixed_to_double(angle);
1885 comp_conf = e_comp_config_get();
1886 if (comp_conf && comp_conf->input_log_enable)
1888 if (event_type != TIZEN_REMOTE_SURFACE_EVENT_TYPE_TOUCH_MOVE)
1890 wl_client_get_credentials(client, &pid, NULL, NULL);
1891 ELOGF("TRS", "TRANSFER Touch event [pid: %d -> pid: %d (ec: %p)] type: %d, time: %d",
1892 NULL, pid, ec?ec->netwm.pid:-1, ec, event_type, time);
1893 ELOGF("TRS", "\tDetail: device: %d, button: %d, x: %d, y: %d, clas: %d, identifier: %20s",
1894 NULL, device, button, x, y, clas, identifier);
1898 if (eclas == ECORE_DEVICE_CLASS_TOUCH)
1902 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_TOUCH_DOWN:
1903 e_client_touch_update_send(ec,
1907 eradx, erady, epressure, eangle,
1909 e_client_touch_send(ec,
1914 eradx, erady, epressure, eangle,
1917 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_TOUCH_UP:
1918 e_client_touch_send(ec,
1923 eradx, erady, epressure, eangle,
1926 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_TOUCH_MOVE:
1927 e_client_touch_update_send(ec,
1931 eradx, erady, epressure, eangle,
1935 ERR("Not supported event_type(%d)", event_type);
1942 _remote_surface_cb_touch_cancel_transfer(struct wl_client *client, struct wl_resource *resource)
1944 E_Comp_Wl_Remote_Provider *provider;
1945 E_Comp_Wl_Remote_Surface *remote_surface;
1948 E_Comp_Config *comp_conf = NULL;
1951 remote_surface = wl_resource_get_user_data(resource);
1952 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
1953 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
1954 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider);
1955 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider->common.ec);
1957 provider = remote_surface->provider;
1958 ec = provider->common.ec;
1960 if (e_object_is_del(E_OBJECT(ec))) return;
1962 comp_conf = e_comp_config_get();
1963 if (comp_conf && comp_conf->input_log_enable)
1965 wl_client_get_credentials(client, &pid, NULL, NULL);
1966 ELOGF("TRS", "TRANSFER Touch cancel [pid: %d -> pid: %d (ec: %p)]",
1967 NULL, pid, ec?ec->netwm.pid:-1, ec);
1970 e_client_touch_cancel_send(ec);
1974 _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)
1976 E_Comp_Wl_Remote_Provider *provider;
1977 E_Comp_Wl_Remote_Surface *remote_surface;
1980 Ecore_Device *edev = NULL;
1981 Ecore_Device_Class eclas = ECORE_DEVICE_CLASS_NONE;
1983 E_Comp_Config *comp_conf = NULL;
1986 remote_surface = wl_resource_get_user_data(resource);
1987 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
1988 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
1989 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider);
1990 EINA_SAFETY_ON_NULL_RETURN(remote_surface->provider->common.ec);
1992 provider = remote_surface->provider;
1993 ec = provider->common.ec;
1995 if (e_object_is_del(E_OBJECT(ec))) return;
1997 /* identify class */
1998 eclas = _device_class_convert_to_ecore(clas);
1999 if (eclas == ECORE_DEVICE_CLASS_NONE)
2001 ERR("Not supported device class(%d) subclass(%d) identifier(%s)",
2002 clas, subclas, identifier);
2006 comp_conf = e_comp_config_get();
2007 if (comp_conf && comp_conf->input_log_enable)
2009 wl_client_get_credentials(client, &pid, NULL, NULL);
2010 ELOGF("TRS", "TRANSFER Key event [pid: %d -> pid: %d (ec: %p)] type: %d, time: %d",
2011 NULL, pid, ec?ec->netwm.pid:-1, ec, event_type, time);
2012 ELOGF("TRS", "\tDetail: keycode: %d, clas: %d, identifier: %20s",
2013 NULL, keycode, clas, identifier);
2016 /* find ecore device*/
2017 edev = _device_get_by_identifier(identifier, eclas);
2019 if (eclas == ECORE_DEVICE_CLASS_KEYBOARD)
2023 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_KEY_DOWN:
2024 e_client_key_send(ec,
2030 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_KEY_UP:
2031 e_client_key_send(ec,
2037 case TIZEN_REMOTE_SURFACE_EVENT_TYPE_KEY_CANCEL:
2038 e_client_key_cancel(ec,
2044 ERR("Not supported event_type(%d)", event_type);
2051 _remote_surface_cb_visibility_transfer(struct wl_client *client, struct wl_resource *resource, uint32_t visibility_type)
2053 E_Comp_Wl_Remote_Surface *remote_surface;
2055 remote_surface = wl_resource_get_user_data(resource);
2056 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2057 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2059 if (visibility_type == TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_INVISIBLE)
2061 _remote_surface_visible_set(remote_surface, EINA_FALSE);
2063 else if (visibility_type == TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_VISIBLE)
2065 _remote_surface_visible_set(remote_surface, EINA_TRUE);
2070 _remote_surface_cb_owner_set(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface_resource)
2072 E_Comp_Wl_Remote_Surface *remote_surface;
2073 E_Client *owner = NULL;
2074 Eina_List *surfaces;
2076 remote_surface = wl_resource_get_user_data(resource);
2077 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2078 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2080 if (surface_resource)
2081 owner = wl_resource_get_user_data(surface_resource);
2083 if (remote_surface->ec == owner) return;
2084 if (remote_surface->ec)
2086 surfaces = eina_hash_find(_rsm->consumer_hash, &remote_surface->ec);
2089 eina_hash_del_by_key(_rsm->consumer_hash, &remote_surface->ec);
2090 surfaces = eina_list_remove(surfaces, remote_surface);
2092 _remote_surface_client_set(remote_surface->ec, EINA_FALSE);
2094 eina_hash_add(_rsm->consumer_hash, &remote_surface->ec, surfaces);
2098 remote_surface->ec = owner;
2100 if ((remote_surface->ec) && (remote_surface->provider))
2102 surfaces = eina_hash_find(_rsm->consumer_hash, &remote_surface->ec);
2105 surfaces = eina_list_append(surfaces, remote_surface);
2106 eina_hash_add(_rsm->consumer_hash, &remote_surface->ec, surfaces);
2109 surfaces = eina_list_append(surfaces, remote_surface);
2110 _remote_surface_client_set(remote_surface->ec, EINA_TRUE);
2113 if (remote_surface->provider)
2114 _remote_provider_onscreen_parent_calculate(remote_surface->provider);
2118 _remote_surface_cb_region_create(struct wl_client *client, struct wl_resource *remote_surface_resource, uint32_t id)
2120 struct wl_resource *resource;
2121 E_Comp_Wl_Remote_Surface *remote_surface;
2122 E_Comp_Wl_Remote_Region *region;
2123 E_Comp_Wl_Remote_Provider *provider;
2125 remote_surface = wl_resource_get_user_data(remote_surface_resource);
2126 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2127 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2129 resource = wl_resource_create(client,
2130 &tizen_remote_surface_region_interface,
2135 ERR("Could not create tizen remote region resource: %m");
2136 wl_client_post_no_memory(client);
2140 region = E_NEW(E_Comp_Wl_Remote_Region, 1);
2143 wl_client_post_no_memory(client);
2144 wl_resource_destroy(resource);
2147 region->remote_surface = remote_surface;
2148 region->resource = resource;
2149 region->geometry.x = -1;
2150 region->geometry.y = -1;
2151 region->geometry.w = -1;
2152 region->geometry.h = -1;
2153 remote_surface->regions = eina_list_append(remote_surface->regions, region);
2155 wl_resource_set_implementation(resource,
2156 &_remote_region_interface,
2158 _remote_region_cb_resource_destroy);
2160 //update provider's region rect list
2161 provider = remote_surface->provider;
2162 if ((provider) && (provider->onscreen_parent == remote_surface))
2164 _remote_provider_rect_add(provider, ®ion->geometry);
2169 _remote_surface_cb_release(struct wl_client *client, struct wl_resource *resource, struct wl_resource *remote_buffer_resource)
2171 E_Comp_Wl_Remote_Surface *remote_surface;
2172 E_Comp_Wl_Remote_Buffer *remote_buffer;
2174 remote_surface = wl_resource_get_user_data(resource);
2175 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2176 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2178 remote_buffer = _e_comp_wl_remote_buffer_get(remote_surface, remote_buffer_resource);
2179 EINA_SAFETY_ON_NULL_RETURN(remote_buffer);
2181 if (remote_surface->version >= 2)
2183 E_Comp_Wl_Buffer *buf = NULL;
2185 if (remote_buffer->ref.buffer &&
2186 remote_buffer->ref.buffer->resource)
2187 buf = remote_buffer->ref.buffer;
2189 e_comp_wl_buffer_reference(&remote_buffer->ref, NULL);
2191 /*Send release event to provider*/
2192 if (remote_surface->provider &&
2193 remote_surface->provider->buffer_mode &&
2194 buf && buf->busy == 0)
2196 if (remote_surface->provider->buffer_mode == 1 ||
2197 (remote_surface->provider->buffer_mode == 2 &&
2198 remote_surface->provider->vis_ref == 0))
2200 E_Client *ec = remote_surface->provider->common.ec;
2201 e_pixmap_buffer_clear(ec->pixmap, EINA_TRUE);
2208 _remote_surface_cb_remote_render_set(struct wl_client *client, struct wl_resource *resource, uint32_t set)
2210 E_Comp_Wl_Remote_Surface *remote_surface;
2211 E_Comp_Wl_Remote_Source *source = NULL;
2213 remote_surface = wl_resource_get_user_data(resource);
2214 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2215 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2217 source = remote_surface->source;
2218 if (!source) return;
2220 if (remote_surface->remote_render == set)
2223 remote_surface->remote_render = set;
2224 _remote_source_offscreen_set(source, set);
2228 _remote_surface_cb_changed_buffer_event_filter_set(struct wl_client *client,
2229 struct wl_resource *rsurf_res,
2230 enum tizen_remote_surface_changed_buffer_event_filter filter)
2232 E_Comp_Wl_Remote_Surface *rs;
2234 rs = wl_resource_get_user_data(rsurf_res);
2235 EINA_SAFETY_ON_NULL_RETURN(rs);
2236 EINA_SAFETY_ON_FALSE_RETURN(rs->valid);
2238 if (filter == TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_EVENT_FILTER_NONE)
2239 rs->changed_buff_ev_filter.use = EINA_FALSE;
2241 rs->changed_buff_ev_filter.use = EINA_TRUE;
2243 rs->changed_buff_ev_filter.filter = filter;
2245 RSMINF("use:%d filter:%u", rs->ec, "SURFACE", rs,
2246 rs->changed_buff_ev_filter.use,
2247 rs->changed_buff_ev_filter.filter);
2251 _remote_surface_cb_curr_buff_get(struct wl_client *client,
2252 struct wl_resource *rsurf_res,
2253 enum tizen_remote_surface_buffer_type buff_type,
2254 uint32_t req_serial)
2256 E_Comp_Wl_Remote_Surface *rs;
2259 rs = wl_resource_get_user_data(rsurf_res);
2260 EINA_SAFETY_ON_NULL_RETURN(rs);
2261 EINA_SAFETY_ON_FALSE_RETURN(rs->valid);
2263 RSMINF("buff_type:%u req_serial:%u",rs->ec, "SURFACE", rs,
2264 buff_type, req_serial);
2266 /* compare buffer type with filter value of changed_buffer event */
2267 res = _remote_surface_changed_buff_ev_filter_check(rs, buff_type);
2268 EINA_SAFETY_ON_FALSE_RETURN(res);
2270 /* setup request info before sending current buffer */
2271 rs->req_curr_buff.set = EINA_TRUE;
2272 rs->req_curr_buff.type = buff_type;
2273 rs->req_curr_buff.serial = req_serial;
2275 RSMINF("buff_type:%u req_serial:%u", rs->ec, "SURFACE", rs,
2276 buff_type, req_serial);
2278 /* send current buffer to the requesting client */
2279 res = _remote_surface_buff_send(rs);
2280 EINA_SAFETY_ON_FALSE_GOTO(res, err_cleanup);
2285 rs->req_curr_buff.set = EINA_FALSE;
2286 rs->req_curr_buff.type = 0;
2287 rs->req_curr_buff.serial = 0;
2290 static const struct tizen_remote_surface_interface _remote_surface_interface =
2292 _remote_surface_cb_destroy,
2293 _remote_surface_cb_redirect,
2294 _remote_surface_cb_unredirect,
2295 _remote_surface_cb_mouse_event_transfer,
2296 _remote_surface_cb_mouse_wheel_transfer,
2297 _remote_surface_cb_touch_event_transfer,
2298 _remote_surface_cb_touch_cancel_transfer,
2299 _remote_surface_cb_key_event_transfer,
2300 _remote_surface_cb_visibility_transfer,
2301 _remote_surface_cb_owner_set,
2302 _remote_surface_cb_region_create,
2303 _remote_surface_cb_release,
2304 _remote_surface_cb_remote_render_set,
2305 _remote_surface_cb_changed_buffer_event_filter_set,
2306 _remote_surface_cb_curr_buff_get,
2310 _remote_manager_cb_provider_create(struct wl_client *client, struct wl_resource *res_remote_manager, uint32_t id, struct wl_resource *surface_resource)
2312 struct wl_resource *resource;
2313 E_Comp_Wl_Remote_Provider *provider;
2318 EINA_SAFETY_ON_NULL_RETURN(_rsm);
2320 ec = e_client_from_surface_resource(surface_resource);
2321 EINA_SAFETY_ON_NULL_RETURN(ec);
2323 if (e_object_is_del(E_OBJECT(ec))) return;
2325 version = wl_resource_get_version(res_remote_manager);
2326 resource = wl_resource_create(client,
2327 &tizen_remote_surface_provider_interface,
2331 ERR("Could not create tizen remote surface provider resource: %m");
2332 wl_client_post_no_memory(client);
2336 provider = E_NEW(E_Comp_Wl_Remote_Provider, 1);
2339 wl_client_post_no_memory(client);
2340 wl_resource_destroy(resource);
2343 provider->common.ec = ec;
2344 provider->resource = resource;
2346 wl_resource_set_implementation(resource,
2347 &_remote_provider_interface,
2349 _remote_provider_cb_resource_destroy);
2351 eina_hash_add(_rsm->provider_hash, &ec, provider);
2353 RSMINF("Created resource(%p)",
2354 ec, "PROVIDER", provider, resource);
2356 _remote_provider_client_set(ec, EINA_TRUE);
2357 _remote_provider_offscreen_set(provider, EINA_TRUE);
2359 /* send resource id */
2360 res_id = e_pixmap_res_id_get(ec->pixmap);
2361 tizen_remote_surface_provider_send_resource_id(resource, res_id);
2363 /* set buffer mode */
2364 provider->buffer_mode = e_config->rsm_buffer_release_mode;
2368 _remote_manager_cb_surface_create(struct wl_client *client,
2369 struct wl_resource *res_remote_manager,
2372 struct wl_resource *wl_tbm)
2374 struct wl_resource *resource;
2375 E_Comp_Wl_Remote_Surface *remote_surface;
2376 E_Comp_Wl_Remote_Provider *provider = NULL;
2377 E_Comp_Wl_Remote_Source *source = NULL;
2384 EINA_SAFETY_ON_NULL_RETURN(_rsm);
2386 version = wl_resource_get_version(res_remote_manager);
2387 resource = wl_resource_create(client,
2388 &tizen_remote_surface_interface,
2392 ERR("Could not create tizen remote surface resource: %m");
2393 wl_client_post_no_memory(client);
2397 remote_surface = E_NEW(E_Comp_Wl_Remote_Surface, 1);
2398 if (!remote_surface)
2400 wl_client_post_no_memory(client);
2401 wl_resource_destroy(resource);
2404 remote_surface->resource = resource;
2405 remote_surface->version = wl_resource_get_version(resource);
2406 remote_surface->redirect = EINA_FALSE;
2407 remote_surface->valid = EINA_FALSE;
2409 wl_resource_set_implementation(resource,
2410 &_remote_surface_interface,
2412 _remote_surface_cb_resource_destroy);
2414 ec = e_pixmap_find_client_by_res_id(res_id);
2417 ERR("Could not find client by res_id(%u)", res_id);
2423 ERR("wayland_tbm resource is NULL");
2427 provider = _remote_provider_find(ec);
2430 /* check the privilege for the client which wants to be the remote surface of normal UI client */
2431 wl_client_get_credentials(client, &pid, &uid, NULL);
2432 res = e_security_privilege_check(pid, uid, E_PRIVILEGE_INTERNAL_DEFAULT_PLATFORM);
2436 "Privilege Check Failed! DENY creating tizen_remote_surface pid:%d",
2441 if (version >= TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION)
2443 if (e_comp_wl_subsurface_check(ec))
2445 ERR("Subsurface could not be source client");
2450 source = _remote_source_get(ec);
2451 if (!source) goto fail;
2455 ERR("Could not support tizen_remote_surface to client :%d", pid);
2460 remote_surface->provider = provider;
2461 remote_surface->source = source;
2462 remote_surface->wl_tbm = wl_tbm;
2464 /* Add destroy listener for wl_tbm resource */
2465 remote_surface->tbm_destroy_listener.notify = _remote_surface_cb_tbm_destroy;
2466 wl_resource_add_destroy_listener((struct wl_resource *)wl_tbm, &remote_surface->tbm_destroy_listener);
2469 provider->common.surfaces = eina_list_append(provider->common.surfaces, remote_surface);
2471 source->common.surfaces = eina_list_append(source->common.surfaces, remote_surface);
2473 RSMINF("Created resource(%p) ec(%p) provider(%p) source(%p) version(%d)",
2474 remote_surface->ec, "SURFACE", remote_surface,
2475 resource, ec, provider, source, remote_surface->version);
2477 remote_surface->valid = EINA_TRUE;
2480 _remote_surface_ignore_output_transform_send(&provider->common);
2482 _remote_surface_ignore_output_transform_send(&source->common);
2487 tizen_remote_surface_send_missing(resource);
2491 _remote_manager_cb_surface_bind(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface_resource, struct wl_resource *remote_surface_resource)
2493 E_Comp_Wl_Remote_Surface *remote_surface;
2494 E_Comp_Wl_Remote_Provider *provider;
2495 E_Client *ec = NULL;
2497 remote_surface = wl_resource_get_user_data(remote_surface_resource);
2498 EINA_SAFETY_ON_NULL_RETURN(remote_surface);
2499 EINA_SAFETY_ON_FALSE_RETURN(remote_surface->valid);
2501 provider = remote_surface->provider;
2502 if (!provider) return;
2504 if (surface_resource)
2505 ec = e_client_from_surface_resource(surface_resource);
2507 _remote_surface_bind_client(remote_surface, ec);
2509 _remote_surface_ignore_output_transform_send(&provider->common);
2513 _remote_manager_cb_destroy(struct wl_client *client, struct wl_resource *resource)
2515 wl_resource_destroy(resource);
2519 _remote_manager_cb_surface_create_with_wl_surface(struct wl_client *client,
2520 struct wl_resource *res_remote_manager,
2523 struct wl_resource *wl_tbm,
2524 struct wl_resource *surface_resource)
2526 struct wl_resource *resource;
2527 E_Comp_Wl_Remote_Surface *remote_surface = NULL;
2528 E_Comp_Wl_Remote_Provider *provider = NULL;
2529 E_Comp_Wl_Remote_Source *source = NULL;
2530 E_Client *ec, *provider_ec;
2531 Eina_List *surfaces;
2537 EINA_SAFETY_ON_NULL_RETURN(_rsm);
2539 version = wl_resource_get_version(res_remote_manager);
2540 resource = wl_resource_create(client,
2541 &tizen_remote_surface_interface,
2545 ERR("Could not create tizen remote surface resource: %m");
2546 wl_client_post_no_memory(client);
2550 remote_surface = E_NEW(E_Comp_Wl_Remote_Surface, 1);
2551 if (!remote_surface)
2553 wl_client_post_no_memory(client);
2554 wl_resource_destroy(resource);
2558 ec = (E_Client *)e_client_from_surface_resource(surface_resource);
2561 ERR("Could not find consumer E_Client by resource:%p", surface_resource);
2562 wl_resource_destroy(resource);
2563 E_FREE(remote_surface);
2567 remote_surface->ec = ec;
2568 remote_surface->resource = resource;
2569 remote_surface->version = wl_resource_get_version(resource);
2570 remote_surface->redirect = EINA_FALSE;
2571 remote_surface->valid = EINA_FALSE;
2573 wl_resource_set_implementation(resource,
2574 &_remote_surface_interface,
2576 _remote_surface_cb_resource_destroy);
2578 provider_ec = e_pixmap_find_client_by_res_id(res_id);
2581 ERR("Could not find client by res_id(%u)", res_id);
2587 ERR("wayland_tbm resource is NULL");
2591 provider = _remote_provider_find(provider_ec);
2594 /* check the privilege for the client which wants to be the remote surface of normal UI client */
2595 wl_client_get_credentials(client, &pid, &uid, NULL);
2596 res = e_security_privilege_check(pid, uid, E_PRIVILEGE_INTERNAL_DEFAULT_PLATFORM);
2600 "Privilege Check Failed! DENY creating tizen_remote_surface pid:%d",
2605 if (version >= TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION)
2607 if (e_comp_wl_subsurface_check(provider_ec))
2609 ERR("Subsurface could not be source client");
2614 source = _remote_source_get(provider_ec);
2615 if (!source) goto fail;
2619 ERR("Could not support tizen_remote_surface to client :%d", pid);
2624 remote_surface->provider = provider;
2625 remote_surface->source = source;
2626 remote_surface->wl_tbm = wl_tbm;
2628 /* Add destroy listener for wl_tbm resource */
2629 remote_surface->tbm_destroy_listener.notify = _remote_surface_cb_tbm_destroy;
2630 wl_resource_add_destroy_listener((struct wl_resource *)wl_tbm, &remote_surface->tbm_destroy_listener);
2632 /* Add to consumer hash and set consumer flag of ec */
2633 surfaces = eina_hash_find(_rsm->consumer_hash, &remote_surface->ec);
2636 surfaces = eina_list_append(surfaces, remote_surface);
2637 eina_hash_add(_rsm->consumer_hash, &remote_surface->ec, surfaces);
2640 surfaces = eina_list_append(surfaces, remote_surface);
2641 _remote_surface_client_set(remote_surface->ec, EINA_TRUE);
2643 /* Add to provider or source's surface list */
2645 provider->common.surfaces = eina_list_append(provider->common.surfaces, remote_surface);
2647 source->common.surfaces = eina_list_append(source->common.surfaces, remote_surface);
2649 RSMINF("Created resource(%p) provider_ec(%p) provider(%p) source(%p) version(%d)",
2650 remote_surface->ec, "SURFACE", remote_surface,
2651 resource, provider_ec, provider, source, remote_surface->version);
2653 remote_surface->valid = EINA_TRUE;
2656 _remote_surface_ignore_output_transform_send(&provider->common);
2658 _remote_surface_ignore_output_transform_send(&source->common);
2663 tizen_remote_surface_send_missing(resource);
2666 static const struct tizen_remote_surface_manager_interface _remote_manager_interface =
2668 _remote_manager_cb_provider_create,
2669 _remote_manager_cb_surface_create,
2670 _remote_manager_cb_surface_bind,
2671 _remote_manager_cb_destroy,
2672 _remote_manager_cb_surface_create_with_wl_surface,
2676 _remote_manager_cb_unbind(struct wl_resource *res_remote_manager)
2678 //nothing to do yet.
2682 _remote_manager_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t ver, uint32_t id)
2684 struct wl_resource *res_remote_manager;
2686 res_remote_manager = wl_resource_create(client,
2687 &tizen_remote_surface_manager_interface,
2690 EINA_SAFETY_ON_NULL_GOTO(res_remote_manager, err);
2692 wl_resource_set_implementation(res_remote_manager,
2693 &_remote_manager_interface,
2695 _remote_manager_cb_unbind);
2699 ERR("Could not create tizen_remote_surface_manager_interface res: %m");
2700 wl_client_post_no_memory(client);
2704 _image_save_type_check(E_Client *ec)
2706 if (ec->skip_save_img) return EINA_FALSE;
2708 if (e_policy_client_is_lockscreen(ec) ||
2709 e_policy_client_is_home_screen(ec) ||
2710 e_policy_client_is_quickpanel(ec) ||
2711 e_policy_client_is_volume(ec) ||
2712 e_policy_client_is_volume_tv(ec) ||
2713 e_policy_client_is_floating(ec) ||
2714 e_policy_client_is_cursor(ec) ||
2715 e_policy_client_is_subsurface(ec) ||
2716 e_policy_client_is_cbhm(ec) ||
2717 e_policy_client_is_toast_popup(ec) ||
2718 e_policy_client_is_keyboard(ec) ||
2719 e_policy_client_is_keyboard_sub(ec) ||
2720 e_policy_client_is_keyboard_magnifier(ec))
2727 _e_comp_wl_remote_cb_client_del(void *data, E_Client *ec)
2729 E_Comp_Wl_Remote_Provider *provider;
2730 E_Comp_Wl_Remote_Source *source;
2731 E_Comp_Wl_Remote_Surface *remote_surface;
2732 Eina_List *surfaces;
2734 if ((provider = eina_hash_find(_rsm->provider_hash, &ec)))
2736 eina_hash_del(_rsm->provider_hash, &ec, provider);
2737 EINA_LIST_FREE(provider->common.surfaces, remote_surface)
2739 if (remote_surface->provider == provider)
2741 /* unset remote buffer from provider */
2742 if (remote_surface->bind_ec)
2743 _remote_surface_bind_client(remote_surface, NULL);
2745 remote_surface->provider = NULL;
2746 //notify of this ejection to remote surface_resource
2747 tizen_remote_surface_send_missing(remote_surface->resource);
2750 _remote_provider_offscreen_set(provider, EINA_FALSE);
2751 wl_resource_set_user_data(provider->resource, NULL);
2755 if ((source = _remote_source_find(ec)))
2757 _remote_source_destroy(source);
2760 if ((surfaces = eina_hash_find(_rsm->consumer_hash, &ec)))
2762 EINA_LIST_FREE(surfaces, remote_surface)
2764 remote_surface->ec = NULL;
2765 if (remote_surface->provider)
2766 _remote_provider_onscreen_parent_calculate(remote_surface->provider);
2768 eina_hash_del_by_key(_rsm->consumer_hash, &ec);
2771 if ((remote_surface = eina_hash_find(_rsm->bind_surface_hash, &ec)))
2773 eina_hash_del(_rsm->bind_surface_hash, &ec, remote_surface);
2774 if (remote_surface->bind_ec == ec)
2775 _remote_surface_bind_client(remote_surface, NULL);
2780 _e_comp_wl_remote_cb_hook_action_change(void *d EINA_UNUSED, E_Process *epro, void *user)
2782 E_Process_Action act;
2783 E_Client *ec = NULL;
2784 E_Client *base_ec = NULL;
2787 act = *(E_Process_Action*)user;
2789 if (act == E_PROCESS_ACT_ACTIVATE)
2791 EINA_LIST_FOREACH(epro->ec_list, l, ec)
2793 e_comp_wl_capture_client_image_save_cancel(ec);
2794 ec->saved_img = EINA_FALSE;
2797 else if (act == E_PROCESS_ACT_DEACTIVATE)
2799 EINA_LIST_FOREACH(epro->ec_list, l, ec)
2805 if (!_image_save_type_check(ec))
2813 e_comp_wl_remote_surface_image_save(base_ec);
2817 _e_comp_wl_remote_cb_client_show(void *data, int type, void *event)
2819 E_Event_Client *ev = event;
2821 E_Comp_Wl_Remote_Surface *remote_surface;
2823 EINA_SAFETY_ON_NULL_RETURN_VAL(_rsm, ECORE_CALLBACK_PASS_ON);
2826 if (!ec) return ECORE_CALLBACK_PASS_ON;
2828 if (e_object_is_del(E_OBJECT(ec))) return ECORE_CALLBACK_PASS_ON;
2830 if ((remote_surface = eina_hash_find(_rsm->bind_surface_hash, &ec)))
2832 _remote_surface_prebind_send(remote_surface);
2835 return ECORE_CALLBACK_PASS_ON;
2839 _e_comp_wl_remote_cb_visibility_change(void *data, int type, void *event)
2841 E_Event_Client *ev = event;
2843 E_Comp_Wl_Remote_Surface *remote_surface;
2844 Eina_List *surfaces, *l;
2846 EINA_SAFETY_ON_NULL_RETURN_VAL(_rsm, ECORE_CALLBACK_PASS_ON);
2848 E_Process_Hook *process_hook;
2850 if (!_rsm->process_hooks)
2852 process_hook = e_process_hook_add(E_PROCESS_HOOK_ACTION_CHANGE, _e_comp_wl_remote_cb_hook_action_change, NULL);
2853 if (process_hook) _rsm->process_hooks = eina_list_append(_rsm->process_hooks, process_hook);
2857 if (!ec) return ECORE_CALLBACK_PASS_ON;
2859 if (e_object_is_del(E_OBJECT(ec))) return ECORE_CALLBACK_PASS_ON;
2860 if (ec->remote_surface.consumer)
2862 if ((surfaces = eina_hash_find(_rsm->consumer_hash, &ec)))
2864 EINA_LIST_FOREACH(surfaces, l, remote_surface)
2866 _remote_provider_onscreen_parent_calculate(remote_surface->provider);
2871 return ECORE_CALLBACK_PASS_ON;
2875 _e_comp_wl_remote_buffer_cb_destroy(struct wl_listener *listener, void *data)
2877 E_Comp_Wl_Remote_Buffer *remote_buffer;
2878 E_Comp_Wl_Remote_Surface *remote_surface;
2880 remote_buffer = container_of(listener, E_Comp_Wl_Remote_Buffer, destroy_listener);
2881 if (!remote_buffer) return;
2883 if (remote_buffer->destroy_listener.notify)
2885 wl_list_remove(&remote_buffer->destroy_listener.link);
2886 remote_buffer->destroy_listener.notify = NULL;
2889 remote_surface = remote_buffer->remote_surface;
2891 remote_surface->send_remote_bufs = eina_list_remove(remote_surface->send_remote_bufs, remote_buffer);
2893 e_comp_wl_buffer_reference(&remote_buffer->ref, NULL);
2894 free(remote_buffer);
2897 static E_Comp_Wl_Remote_Buffer *
2898 _e_comp_wl_remote_buffer_get(E_Comp_Wl_Remote_Surface *remote_surface, struct wl_resource *remote_buffer_resource)
2900 E_Comp_Wl_Remote_Buffer *remote_buffer = NULL;
2901 struct wl_listener *listener;
2903 listener = wl_resource_get_destroy_listener(remote_buffer_resource, _e_comp_wl_remote_buffer_cb_destroy);
2905 return container_of(listener, E_Comp_Wl_Remote_Buffer, destroy_listener);
2907 if (!(remote_buffer = E_NEW(E_Comp_Wl_Remote_Buffer, 1))) return NULL;
2909 remote_buffer->remote_surface = remote_surface;
2910 remote_buffer->resource = remote_buffer_resource;
2911 remote_buffer->destroy_listener.notify = _e_comp_wl_remote_buffer_cb_destroy;
2912 wl_resource_add_destroy_listener(remote_buffer->resource, &remote_buffer->destroy_listener);
2914 remote_surface->send_remote_bufs = eina_list_append(remote_surface->send_remote_bufs, remote_buffer);
2916 return remote_buffer;
2920 _e_comp_wl_remote_surface_source_update(E_Comp_Wl_Remote_Source *source, E_Comp_Wl_Buffer *buffer, Eina_Bool pending)
2922 E_Comp_Wl_Remote_Surface *remote_surface;
2925 if ((!source) || (!buffer)) return;
2927 EINA_LIST_FOREACH(source->common.surfaces, l, remote_surface)
2929 if (remote_surface->version < TIZEN_REMOTE_SURFACE_CHANGED_BUFFER_SINCE_VERSION)
2932 if (!remote_surface->redirect) continue;
2934 _remote_surface_changed_buff_protocol_send(remote_surface,
2935 TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM,
2939 buffer, NULL, pending);
2944 _e_comp_wl_remote_surface_dummy_fd_get(void)
2946 int fd = 0, blen = 0, len = 0;
2949 Eina_Tmpstr *tmpstr = NULL;
2951 blen = sizeof(buf) - 1;
2953 path = e_util_env_get("XDG_RUNTIME_DIR");
2954 if (!path) return -1;
2956 len = strlen(path) + 34;
2959 strncpy(buf, path, PATH_MAX - 35);
2960 strncat(buf, "/enlightenment_rsm_dummy_fdXXXXXX", 34);
2969 if ((fd = eina_file_mkstemp(buf, &tmpstr)) < 0)
2972 ecore_file_unlink(tmpstr);
2973 eina_tmpstr_del(tmpstr);
2979 _e_comp_wl_remote_surface_state_buffer_set(E_Comp_Wl_Surface_State *state, E_Comp_Wl_Buffer *buffer)
2981 if (state->buffer == buffer) return;
2983 wl_list_remove(&state->buffer_destroy_listener.link);
2984 state->buffer = buffer;
2986 wl_signal_add(&state->buffer->destroy_signal,
2987 &state->buffer_destroy_listener);
2991 _e_comp_wl_remote_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
2993 E_Comp_Wl_Remote_Provider *provider;
2994 E_Comp_Wl_Remote_Source *source;
2995 E_Comp_Wl_Remote_Surface *surface;
2996 struct wl_resource *cb;
2997 Eina_Rectangle *dmg;
2998 int x = 0, y = 0, sx = 0, sy = 0;
2999 E_Comp_Wl_Buffer *buffer;
3001 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
3002 E_Comp_Wl_Buffer_Viewport *vp = &ec->comp_data->scaler.buffer_viewport;
3004 if (vp->buffer.transform != state->buffer_viewport.buffer.transform)
3006 int transform_change = (4 + state->buffer_viewport.buffer.transform - vp->buffer.transform) & 0x3;
3008 ELOGF("TRANSFORM", "buffer_transform changed: old(%d) new(%d)",
3010 vp->buffer.transform, state->buffer_viewport.buffer.transform);
3012 if (transform_change == vp->wait_for_transform_change)
3013 vp->wait_for_transform_change = 0;
3016 ec->comp_data->scaler.buffer_viewport = state->buffer_viewport;
3018 if (state->new_attach)
3019 e_comp_wl_surface_attach(ec, state->buffer);
3021 _e_comp_wl_remote_surface_state_buffer_set(state, NULL);
3023 if (state->new_attach)
3025 x = ec->client.x, y = ec->client.y;
3027 ec->client.w = state->bw;
3028 ec->client.h = state->bh;
3029 e_client_size_set(ec, state->bw, state->bh);
3031 e_client_shell_configure(ec, x, y, ec->w, ec->h);
3038 state->new_attach = EINA_FALSE;
3040 /* send previous frame done */
3041 EINA_LIST_FOREACH_SAFE(ec->comp_data->frames, l, ll, cb)
3043 wl_callback_send_done(cb, (unsigned int)(ecore_loop_time_get() * 1000));
3044 wl_resource_destroy(cb);
3047 ec->comp_data->frames = eina_list_merge(ec->comp_data->frames,
3049 state->frames = NULL;
3051 /* clear stored damages... */
3052 EINA_LIST_FREE(state->buffer_damages, dmg)
3053 eina_rectangle_free(dmg);
3055 EINA_LIST_FREE(state->damages, dmg)
3056 eina_rectangle_free(dmg);
3058 state->buffer_viewport.changed = 0;
3060 wl_signal_emit(&cdata->state_commit_signal, &cdata->surface);
3062 /* send remote buffer to remote surfaces */
3063 buffer = e_pixmap_resource_get(ec->pixmap);
3066 if ((provider = _remote_provider_find(ec)))
3068 EINA_LIST_FOREACH(provider->common.surfaces, l, surface)
3070 if (!surface->redirect) continue;
3071 if (surface->bind_ec)
3073 surface->bind_ec->comp_data->pending.buffer_viewport = ec->comp_data->scaler.buffer_viewport;
3075 _e_comp_wl_remote_surface_state_buffer_set(&surface->bind_ec->comp_data->pending, buffer);
3076 surface->bind_ec->comp_data->pending.sx = sx;
3077 surface->bind_ec->comp_data->pending.sy = sy;
3078 surface->bind_ec->comp_data->pending.new_attach = EINA_TRUE;
3080 e_comp_wl_surface_commit(surface->bind_ec);
3082 /* need to prepare hwc whenever buffer changed */
3083 e_comp_render_queue();
3087 _remote_surface_changed_buff_protocol_send(surface,
3088 TIZEN_REMOTE_SURFACE_BUFFER_TYPE_TBM,
3092 buffer, NULL, EINA_FALSE);
3096 else if ((source = _remote_source_find(ec)))
3098 _e_comp_wl_remote_surface_source_update(source, buffer, EINA_FALSE);
3101 /* send frame done */
3102 e_pixmap_image_clear(ec->pixmap, 1);
3107 _e_comp_wl_remote_surface_subsurface_commit(E_Comp_Wl_Remote_Provider *parent_provider,
3110 E_Comp_Wl_Remote_Surface *onscreen_parent;
3112 Eina_Rectangle *rect;
3116 Eina_Bool first_skip = EINA_TRUE;
3117 E_Comp_Wl_Buffer *buffer;
3119 if (!e_comp_wl_subsurface_commit(ec)) return EINA_FALSE;
3121 buffer = e_pixmap_resource_get(ec->pixmap);
3122 if (!buffer) return EINA_TRUE;
3124 if (buffer->type != E_COMP_WL_BUFFER_TYPE_SHM) return EINA_TRUE;
3126 /* TODO : store and use multiple onscreen_parent for geometry calculation */
3127 onscreen_parent = parent_provider->onscreen_parent;
3128 if (!onscreen_parent) return EINA_TRUE;
3130 if (!evas_object_visible_get(ec->frame)) return EINA_TRUE;
3132 evas_object_geometry_get(ec->frame, &fx, &fy, &fw, &fh);
3134 e_comp_wl_subsurface_position_get(ec, &sx, &sy);
3136 EINA_LIST_FOREACH(parent_provider->common.ec->comp_data->remote_surface.regions, l, rect)
3138 E_Comp_Wl_Remote_Region *region;
3140 region = container_of(rect, E_Comp_Wl_Remote_Region, geometry);
3145 if (onscreen_parent->ec)
3147 x += onscreen_parent->ec->x;
3148 y += onscreen_parent->ec->y;
3151 if ((fx == x) && (fy == y) && (first_skip))
3153 first_skip = EINA_FALSE;
3157 w = ec->comp_data->width_from_viewport;
3158 h = ec->comp_data->height_from_viewport;
3161 * w = (int) (w * ((double)rect->w / parent_provider->ec->w));
3162 * h = (int) (h * ((double)rect->h / parent_provider->ec->h));
3165 if (!region->mirror)
3167 region->mirror = e_comp_object_util_mirror_add(ec->frame);
3168 evas_object_layer_set(region->mirror, ec->layer);
3169 evas_object_stack_below(region->mirror, ec->frame);
3170 evas_object_show(region->mirror);
3171 evas_object_event_callback_add(region->mirror, EVAS_CALLBACK_DEL, _remote_region_cb_mirror_del, region);
3173 if (!region->mirror) continue;
3175 evas_object_move(region->mirror, x, y);
3176 evas_object_resize(region->mirror, w, h);
3183 _e_comp_wl_remote_source_save_done_cb(void *data, E_Client* ec, const Eina_Stringshare *dest, E_Capture_Save_State state)
3185 E_Comp_Wl_Remote_Source *source = NULL;
3187 if (state != E_CAPTURE_SAVE_STATE_DONE)
3189 RSMDBG("SAVE_DONE_CB state:%d, %s", ec, "SOURCE", data, state, dest);
3193 source = _remote_source_find(ec);
3194 if (!source) return;
3196 /* remove previous file */
3197 if ((source->image_path) && (e_util_strcmp(source->image_path, dest)))
3199 if (!e_config->hold_prev_win_img)
3201 RSMDBG("IMG del %s", ec, "SOURCE", source, source->image_path);
3202 ecore_file_remove(source->image_path);
3206 eina_stringshare_del(source->image_path);
3207 source->image_path = eina_stringshare_ref(dest);
3208 _remote_source_send_image_update(source);
3210 ec->saved_img = EINA_TRUE;
3214 e_comp_wl_remote_surface_bound_provider_ec_get(E_Client *ec)
3216 E_Comp_Wl_Remote_Surface *remote_surface;
3218 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
3219 EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), NULL);
3220 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, NULL);
3222 remote_surface = eina_hash_find(_rsm->bind_surface_hash, &ec);
3223 if (!remote_surface || !remote_surface->provider) return NULL;
3225 return remote_surface->provider->common.ec;
3229 e_comp_wl_remote_surface_commit(E_Client *ec)
3231 E_Comp_Wl_Remote_Provider *provider;
3232 E_Comp_Wl_Remote_Source *source = NULL;
3233 E_Comp_Wl_Subsurf_Data *sdata;
3234 E_Client *parent, *offscreen_parent;
3236 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
3237 EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), EINA_FALSE);
3238 EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
3240 source = _remote_source_find(ec);
3243 if (source->common.is_offscreen)
3245 _e_comp_wl_remote_surface_state_commit(ec, &ec->comp_data->pending);
3249 //send update to remote_surface of source client
3250 _e_comp_wl_remote_surface_source_update(source, ec->comp_data->pending.buffer, EINA_TRUE);
3252 //do normal commit callback process
3256 /* subsurface case */
3257 if (e_comp_wl_subsurface_check(ec))
3259 /* check for valid subcompositor data */
3260 parent = e_comp_wl_subsurface_parent_get(ec);
3264 if (!parent->comp_data)
3267 if (e_object_is_del(E_OBJECT(parent)))
3270 if (!(sdata = parent->comp_data->sub.data))
3273 if (!sdata->remote_surface.offscreen_parent)
3276 offscreen_parent = sdata->remote_surface.offscreen_parent;
3278 provider = _remote_provider_find(offscreen_parent);
3279 if (!provider) return EINA_FALSE;
3281 if (!_e_comp_wl_remote_surface_subsurface_commit(provider, ec))
3286 if (!(provider = _remote_provider_find(ec)))
3289 _e_comp_wl_remote_surface_state_commit(ec, &ec->comp_data->pending);
3295 e_comp_wl_remote_surface_image_save(E_Client *ec)
3297 E_Comp_Wl_Remote_Source *src;
3298 Eina_Stringshare *dir, *name;
3300 if (!e_config->save_win_buffer) return;
3301 if (e_object_is_del(E_OBJECT(ec))) return;
3302 if (ec->saved_img) return;
3303 if (ec->ignored) return;
3304 if (!_image_save_type_check(ec)) return;
3306 src = _remote_source_get(ec);
3307 EINA_SAFETY_ON_NULL_RETURN(src);
3309 _remote_source_default_path_get(ec, &dir, &name);
3311 /* for preventing hw reserved memory is used by capture */
3312 e_comp_client_override_add(ec);
3313 e_comp_wl_capture_client_image_save(ec, dir, name, _e_comp_wl_remote_source_save_done_cb, NULL, EINA_FALSE);
3314 e_comp_client_override_del(ec);
3316 eina_stringshare_del(dir);
3317 eina_stringshare_del(name);
3321 e_comp_wl_remote_surface_image_save_cancel(E_Client *ec)
3324 e_comp_wl_capture_client_image_save_cancel(ec);
3328 e_comp_wl_remote_surface_image_save_skip_set(E_Client *ec, Eina_Bool set)
3330 if (e_object_is_del(E_OBJECT(ec))) return;
3332 ec->skip_save_img = set;
3336 e_comp_wl_remote_surface_image_save_skip_get(E_Client *ec)
3338 if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
3339 return ec->skip_save_img;
3344 e_comp_wl_remote_surface_debug_info_get(Eldbus_Message_Iter *iter)
3346 Eldbus_Message_Iter *line_array;
3347 Eina_Iterator *hash_iter;
3348 E_Comp_Wl_Remote_Provider *provider;
3349 E_Comp_Wl_Remote_Source *source;
3351 char info_str[1024];
3353 eldbus_message_iter_arguments_append(iter, "as", &line_array);
3356 eldbus_message_iter_basic_append(line_array,
3358 "Remote Surface not initialized..");
3359 eldbus_message_iter_container_close(iter, line_array);
3364 hash_iter = eina_hash_iterator_data_new(_rsm->provider_hash);
3365 EINA_ITERATOR_FOREACH(hash_iter, provider)
3367 E_Client *ec = provider->common.ec;
3368 E_Comp_Wl_Remote_Surface *remote_surface;
3373 #if defined(__cplusplus) || defined(c_plusplus)
3374 snprintf(info_str, sizeof(info_str),
3375 "%10s [%d] %8p win(0x%08zx) res(%d) pid(%d) vis(%d) name(%s)",
3376 "PROVIDER", idx++, provider,
3377 e_client_util_win_get(ec),
3378 e_pixmap_res_id_get(ec->pixmap),
3381 e_client_util_name_get(ec)?:ec->icccm.cpp_class?:"NO NAME");
3383 snprintf(info_str, sizeof(info_str),
3384 "%10s [%d] %8p win(0x%08zx) res(%d) pid(%d) vis(%d) name(%s)",
3385 "PROVIDER", idx++, provider,
3386 e_client_util_win_get(ec),
3387 e_pixmap_res_id_get(ec->pixmap),
3390 e_client_util_name_get(ec)?:ec->icccm.class?:"NO NAME");
3392 eldbus_message_iter_basic_append(line_array, 's', info_str);
3394 if (provider->common.surfaces)
3396 snprintf(info_str, sizeof(info_str), "%7s", "│");
3397 eldbus_message_iter_basic_append(line_array, 's', info_str);
3400 EINA_LIST_FOREACH(provider->common.surfaces, l, remote_surface)
3402 struct wl_client *wc = NULL;
3403 E_Client *consumer = NULL;
3406 Eina_Bool is_last = 0;
3408 if (!remote_surface->resource) continue;
3410 consumer = remote_surface->ec;
3412 consumer = remote_surface->bind_ec;
3414 wc = wl_resource_get_client(remote_surface->resource);
3416 wl_client_get_credentials(wc, &pid, NULL, NULL);
3418 if ((eina_list_last(provider->common.surfaces) == l))
3419 is_last = EINA_TRUE;
3421 #if defined(__cplusplus) || defined(c_plusplus)
3422 snprintf(info_str, sizeof(info_str),
3423 "%10s CONSUMER [%d] %8p ec(%8p) win(0x%08zx) pid(%d) vis(%d) redirected(%d) name(%s)",
3424 is_last? "└─" : "├─", s_idx++, remote_surface,
3425 consumer ? consumer : NULL,
3426 consumer ? e_client_util_win_get(consumer) : 0,
3428 remote_surface->visible,
3429 remote_surface->redirect,
3430 consumer? e_client_util_name_get(consumer)?:consumer->icccm.cpp_class?:"NO NAME":"NO CONSUMER"
3433 snprintf(info_str, sizeof(info_str),
3434 "%10s CONSUMER [%d] %8p ec(%8p) win(0x%08zx) pid(%d) vis(%d) redirected(%d) name(%s)",
3435 is_last? "└─" : "├─", s_idx++, remote_surface,
3436 consumer ? consumer : NULL,
3437 consumer ? e_client_util_win_get(consumer) : 0,
3439 remote_surface->visible,
3440 remote_surface->redirect,
3441 consumer? e_client_util_name_get(consumer)?:consumer->icccm.class?:"NO NAME":"NO CONSUMER"
3444 eldbus_message_iter_basic_append(line_array, 's', info_str);
3446 eldbus_message_iter_basic_append(line_array, 's', "");
3448 eina_iterator_free(hash_iter);
3452 hash_iter = eina_hash_iterator_data_new(_rsm->source_hash);
3453 EINA_ITERATOR_FOREACH(hash_iter, source)
3455 E_Client *ec = source->common.ec;
3456 E_Comp_Wl_Remote_Surface *remote_surface;
3460 #if defined(__cplusplus) || defined(c_plusplus)
3461 snprintf(info_str, sizeof(info_str),
3462 "%10s [%d] %8p win(0x%08zx) res(%d) pid(%d) offscreen(%d) name(%s)",
3463 "SOURCE", idx++, source,
3464 e_client_util_win_get(ec),
3465 e_pixmap_res_id_get(ec->pixmap),
3467 source->offscreen_ref,
3468 e_client_util_name_get(ec)?:ec->icccm.cpp_class?:"NO NAME");
3470 snprintf(info_str, sizeof(info_str),
3471 "%10s [%d] %8p win(0x%08zx) res(%d) pid(%d) offscreen(%d) name(%s)",
3472 "SOURCE", idx++, source,
3473 e_client_util_win_get(ec),
3474 e_pixmap_res_id_get(ec->pixmap),
3476 source->offscreen_ref,
3477 e_client_util_name_get(ec)?:ec->icccm.class?:"NO NAME");
3479 eldbus_message_iter_basic_append(line_array, 's', info_str);
3481 if (source->common.surfaces)
3483 snprintf(info_str, sizeof(info_str), "%7s", "│");
3484 eldbus_message_iter_basic_append(line_array, 's', info_str);
3487 EINA_LIST_FOREACH(source->common.surfaces, l, remote_surface)
3489 struct wl_client *wc = NULL;
3490 E_Client *consumer = NULL;
3493 Eina_Bool is_last = 0;
3495 if (!remote_surface->resource) continue;
3497 consumer = remote_surface->ec;
3499 consumer = remote_surface->bind_ec;
3501 wc = wl_resource_get_client(remote_surface->resource);
3503 wl_client_get_credentials(wc, &pid, NULL, NULL);
3505 if ((eina_list_last(source->common.surfaces) == l))
3506 is_last = EINA_TRUE;
3508 #if defined(__cplusplus) || defined(c_plusplus)
3509 snprintf(info_str, sizeof(info_str),
3510 "%10s CONSUMER [%d] %8p ec(%8p) win(0x%08zx) pid(%d) vis(%d) redirected(%d) name(%s)",
3511 is_last? "└─" : "├─", s_idx++, remote_surface,
3512 consumer ? consumer : NULL,
3513 consumer ? e_client_util_win_get(consumer) : 0,
3515 remote_surface->visible,
3516 remote_surface->redirect,
3517 consumer? e_client_util_name_get(consumer)?:consumer->icccm.cpp_class?:"NO NAME":"NO CONSUMER"
3520 snprintf(info_str, sizeof(info_str),
3521 "%10s CONSUMER [%d] %8p ec(%8p) win(0x%08zx) pid(%d) vis(%d) redirected(%d) name(%s)",
3522 is_last? "└─" : "├─", s_idx++, remote_surface,
3523 consumer ? consumer : NULL,
3524 consumer ? e_client_util_win_get(consumer) : 0,
3526 remote_surface->visible,
3527 remote_surface->redirect,
3528 consumer? e_client_util_name_get(consumer)?:consumer->icccm.class?:"NO NAME":"NO CONSUMER"
3531 eldbus_message_iter_basic_append(line_array, 's', info_str);
3533 eldbus_message_iter_basic_append(line_array, 's', "");
3535 eina_iterator_free(hash_iter);
3537 eldbus_message_iter_container_close(iter, line_array);
3541 * Get a list of e_clients of tizen remote surface providers which is used in given ec
3542 * NB: caller must free returned Eina_List object after using it.
3545 e_comp_wl_remote_surface_providers_get(E_Client *ec)
3547 E_Comp_Wl_Remote_Provider *prov;
3548 E_Comp_Wl_Remote_Source *src;
3549 E_Comp_Wl_Remote_Surface *rs;
3552 Eina_List *provs = NULL; /* result list */
3553 E_Client *consumer_ec;
3555 /* remote surface providers */
3556 it = eina_hash_iterator_data_new(_rsm->provider_hash);
3557 EINA_ITERATOR_FOREACH(it, prov)
3559 EINA_LIST_FOREACH(prov->common.surfaces, l, rs)
3561 consumer_ec = rs->ec;
3562 if (!consumer_ec) consumer_ec = rs->bind_ec;
3564 if (!consumer_ec) continue;
3565 if (consumer_ec != ec) continue;
3567 /* append provider's ec to result list */
3568 provs = eina_list_append(provs, prov->common.ec);
3572 eina_iterator_free(it);
3574 /* remote sources i.e., normal window */
3575 it = eina_hash_iterator_data_new(_rsm->source_hash);
3576 EINA_ITERATOR_FOREACH(it, src)
3578 EINA_LIST_FOREACH(src->common.surfaces, l, rs)
3580 consumer_ec = rs->ec;
3581 if (!consumer_ec) consumer_ec = rs->bind_ec;
3583 if (!consumer_ec) continue;
3584 if (consumer_ec != ec) continue;
3586 /* append source's ec to result list */
3587 provs = eina_list_append(provs, src->common.ec);
3591 eina_iterator_free(it);
3597 * Get a list of e_clients of tizen remote surface consumers which use given ec
3598 * NB: caller must free returned Eina_List object after using it.
3601 e_comp_wl_remote_surface_consumers_get(E_Client *ec)
3603 Eina_List *consumer_ec_l = NULL; /* result list */
3604 E_Client *consumer_ec;
3605 E_Comp_Wl_Remote_Surface *rs;
3606 E_Comp_Wl_Remote_Provider *provider;
3609 provider = _remote_provider_find(ec);
3610 if (!provider) return NULL;
3612 EINA_LIST_FOREACH(provider->common.surfaces, l, rs)
3614 consumer_ec = rs->ec;
3615 if (!consumer_ec) consumer_ec = rs->bind_ec;
3616 if (!consumer_ec) continue;
3617 if (!consumer_ec->remote_surface.consumer) continue;
3619 consumer_ec_l = eina_list_append(consumer_ec_l, consumer_ec);
3622 return consumer_ec_l;
3626 e_comp_wl_remote_surface_init(void)
3628 E_Comp_Wl_Remote_Manager *rs_manager = NULL;
3630 EINA_SAFETY_ON_NULL_RETURN(e_comp_wl);
3631 EINA_SAFETY_ON_NULL_RETURN(e_comp_wl->wl.disp);
3632 EINA_SAFETY_ON_NULL_RETURN(e_comp->wl_comp_data->tbm.server);
3634 rs_manager = E_NEW(E_Comp_Wl_Remote_Manager, 1);
3635 EINA_SAFETY_ON_NULL_RETURN(rs_manager);
3637 rs_manager->global = wl_global_create(e_comp_wl->wl.disp,
3638 &tizen_remote_surface_manager_interface,
3641 _remote_manager_cb_bind);
3644 E_CLIENT_HOOK_APPEND(rs_manager->client_hooks, E_CLIENT_HOOK_DEL, _e_comp_wl_remote_cb_client_del, NULL);
3647 E_LIST_HANDLER_APPEND(rs_manager->event_hdlrs,
3648 E_EVENT_CLIENT_VISIBILITY_CHANGE,
3649 _e_comp_wl_remote_cb_visibility_change, rs_manager);
3650 E_LIST_HANDLER_APPEND(rs_manager->event_hdlrs,
3651 E_EVENT_CLIENT_SHOW,
3652 _e_comp_wl_remote_cb_client_show, rs_manager);
3654 rs_manager->provider_hash = eina_hash_pointer_new(NULL);
3655 rs_manager->consumer_hash = eina_hash_pointer_new(NULL);
3656 rs_manager->source_hash = eina_hash_pointer_new(NULL);
3657 rs_manager->bind_surface_hash = eina_hash_pointer_new(NULL);
3658 rs_manager->dummy_fd = _e_comp_wl_remote_surface_dummy_fd_get();
3660 if (rs_manager->dummy_fd == -1)
3662 ERR("it's FATAL error, remote surface can't send remote buffer without dummy_fd...");
3664 e_comp_wl_remote_surface_shutdown();
3668 RSMINF("dummy_fd created %d", NULL, "MANAGER", rs_manager, rs_manager->dummy_fd);
3672 E_EVENT_REMOTE_SURFACE_PROVIDER_VISIBILITY_CHANGE = ecore_event_type_new();
3676 e_comp_wl_remote_surface_shutdown(void)
3678 E_Comp_Wl_Remote_Manager *rsm;
3679 E_Comp_Wl_Remote_Provider *provider;
3680 E_Comp_Wl_Remote_Source *source;
3681 E_Comp_Wl_Remote_Surface *remote_surface;
3683 Eina_List *surfaces;
3690 it = eina_hash_iterator_data_new(rsm->provider_hash);
3691 EINA_ITERATOR_FOREACH(it, provider)
3693 EINA_LIST_FREE(provider->common.surfaces, remote_surface)
3695 remote_surface->provider = NULL;
3696 wl_resource_destroy(remote_surface->resource);
3698 wl_resource_destroy(provider->resource);
3700 eina_iterator_free(it);
3702 it = eina_hash_iterator_data_new(rsm->consumer_hash);
3703 EINA_ITERATOR_FOREACH(it, surfaces)
3704 eina_list_free(surfaces);
3705 eina_iterator_free(it);
3707 it = eina_hash_iterator_data_new(rsm->source_hash);
3708 EINA_ITERATOR_FOREACH(it, source)
3710 EINA_LIST_FREE(source->common.surfaces, remote_surface)
3712 remote_surface->source = NULL;
3713 wl_resource_destroy(remote_surface->resource);
3715 _remote_source_destroy(source);
3717 eina_iterator_free(it);
3719 if (rsm->dummy_fd != -1)
3720 close(rsm->dummy_fd);
3722 E_FREE_LIST(rsm->process_hooks, e_process_hook_del);
3724 E_FREE_FUNC(rsm->effect_end, e_comp_object_hook_del);
3725 E_FREE_FUNC(rsm->provider_hash, eina_hash_free);
3726 E_FREE_FUNC(rsm->consumer_hash, eina_hash_free);
3727 E_FREE_FUNC(rsm->source_hash, eina_hash_free);
3728 E_FREE_FUNC(rsm->bind_surface_hash, eina_hash_free);
3730 E_FREE_LIST(rsm->client_hooks, e_client_hook_del);
3731 E_FREE_LIST(rsm->event_hdlrs, ecore_event_handler_del);
3732 wl_global_destroy(rsm->global);