e_client: use e_client_visibility_set/get funtions
[platform/upstream/enlightenment.git] / src / bin / video / e_comp_wl_video.c
1 #include "e_client_video_intern.h"
2 #include "e_video_debug_intern.h"
3 #include "e_info_server_intern.h"
4 #include "e_comp_wl_video_buffer_intern.h"
5 #include "e_zone_video_intern.h"
6 #include "e_comp_wl_viewport_intern.h"
7 #include "e_utils_intern.h"
8 #include "e_client_intern.h"
9
10 #include <tizen-extension-server-protocol.h>
11
12 typedef struct _E_Video_Object E_Video_Object;
13
14 struct _E_Video_Object
15 {
16    struct wl_resource *resource;
17    E_Client *ec;
18    struct
19      {
20         Ecore_Event_Handler *visibility_change;
21         Ecore_Event_Handler *remove;
22      } client_event_handler;
23 };
24
25 static void _e_comp_wl_video_object_setup(E_Video_Object *vo, E_Client *ec);
26
27 static int
28 _e_comp_wl_video_object_prop_id_get(E_Video_Object *vo, const char *name)
29 {
30    const tdm_prop *props;
31    int i, count = 0;
32
33    e_client_video_available_properties_get(vo->ec, &props, &count);
34    for (i = 0; i < count; i++)
35      {
36         if (!strncmp(name, props[i].name, TDM_NAME_LEN))
37           {
38              VDB("check property(%s)", vo->ec, name);
39              return props[i].id;
40           }
41      }
42
43    return -1;
44 }
45
46 static Eina_Bool
47 _e_comp_wl_video_object_ec_cb_remove(void *data, int type, void *event)
48 {
49    E_Event_Client *ev;
50    E_Client *ec;
51    E_Video_Object *vo;
52
53    ev = event;
54
55    ec = ev->ec;
56    vo = data;
57    if (vo->ec != ec) return ECORE_CALLBACK_PASS_ON;
58
59    E_FREE_FUNC(vo->client_event_handler.visibility_change, ecore_event_handler_del);
60    E_FREE_FUNC(vo->client_event_handler.remove, ecore_event_handler_del);
61
62    e_client_video_unset(vo->ec);
63
64    vo->ec = NULL;
65
66    return ECORE_CALLBACK_PASS_ON;
67 }
68
69 static E_Video_Object *
70 _e_comp_wl_video_object_create(struct wl_resource *resource, struct wl_resource *surface)
71 {
72    E_Video_Object *vo;
73    E_Client *ec;
74
75    ec = e_client_from_surface_resource(surface);
76    EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), NULL);
77
78    vo = calloc(1, sizeof *vo);
79    EINA_SAFETY_ON_NULL_RETURN_VAL(vo, NULL);
80
81    vo->resource = resource;
82
83    VIN("create.", ec);
84
85    _e_comp_wl_video_object_setup(vo, ec);
86
87    vo->client_event_handler.remove =
88       ecore_event_handler_add(E_EVENT_CLIENT_REMOVE,
89                               _e_comp_wl_video_object_ec_cb_remove, vo);
90
91    return vo;
92 }
93
94 static void
95 _e_comp_wl_video_object_available_size_send(E_Video_Object *vo)
96 {
97    int minw, minh, maxw, maxh;
98    int align;
99    Eina_Bool res;
100    E_Zone *zone;
101
102    zone = e_comp_zone_find_by_ec(vo->ec);
103    EINA_SAFETY_ON_NULL_RETURN(zone);
104
105    res = e_zone_video_available_size_get(zone,
106                                          &minw, &minh, &maxw, &maxh, &align);
107    if (!res)
108      {
109         VER("Failed to get video available size", vo->ec);
110         return;
111      }
112
113    tizen_video_object_send_size(vo->resource, minw, minh, maxw, maxh, align);
114 }
115
116 static void
117 _e_comp_wl_video_object_available_properties_send(E_Video_Object *vo)
118 {
119    int i, count = 0;
120    const tdm_prop *props;
121    tdm_value value;
122    Eina_Bool res;
123
124    e_client_video_available_properties_get(vo->ec, &props, &count);
125    for (i = 0; i < count; i++)
126      {
127         res = e_client_video_property_get(vo->ec, props[i].id, &value);
128         if (!res)
129           {
130              VER("Failed to get property name %s value %d",
131                  vo->ec, props[i].name, value.u32);
132              continue;
133           }
134
135         tizen_video_object_send_attribute(vo->resource,
136                                           props[i].name, value.u32);
137      }
138 }
139
140 static void
141 _e_comp_wl_video_object_setup(E_Video_Object *vo, E_Client *ec)
142 {
143    vo->ec = ec;
144
145    e_client_video_set(ec);
146
147    _e_comp_wl_video_object_available_size_send(vo);
148    _e_comp_wl_video_object_available_properties_send(vo);
149 }
150
151 static void
152 _e_comp_wl_video_object_resource_destroy(struct wl_resource *resource)
153 {
154    E_Video_Object *vo;
155
156    vo = wl_resource_get_user_data(resource);
157
158    if (vo->ec)
159      {
160         E_FREE_FUNC(vo->client_event_handler.visibility_change, ecore_event_handler_del);
161         E_FREE_FUNC(vo->client_event_handler.remove, ecore_event_handler_del);
162
163         e_client_video_unset(vo->ec);
164      }
165
166    free(vo);
167 }
168
169 static void
170 _e_comp_wl_video_object_handle_destroy(struct wl_client *client, struct wl_resource *resource)
171 {
172    wl_resource_destroy(resource);
173 }
174
175 static void
176 _e_comp_wl_video_object_handle_attribute_set(struct wl_client *client,
177                                          struct wl_resource *resource,
178                                          const char *name,
179                                          int32_t value)
180 {
181    E_Video_Object *vo;
182    tdm_value v;
183    int id;
184
185    vo = wl_resource_get_user_data(resource);
186
187    if (!vo->ec)
188      return;
189
190    VIN("Client(%s):PID(%d) Attribute:%s, Value:%d",
191        vo->ec, e_client_util_name_get(vo->ec) ?: "No Name",
192        vo->ec->netwm.pid, name, value);
193
194    // check available property & count
195    id = _e_comp_wl_video_object_prop_id_get(vo, name);
196    if(id < 0)
197      {
198         VIN("no available property", vo->ec);
199         return;
200      }
201
202    v.u32 = value;
203    e_client_video_property_set(vo->ec, id, v, EINA_FALSE);
204 }
205
206 static Eina_Bool
207 _e_comp_wl_video_object_ec_cb_visibility_change(void *data, int type, void *event)
208 {
209    E_Video_Object *vo;
210    E_Client *ec;
211    E_Event_Client *ev;
212
213    ev = event;
214    vo = data;
215    if (vo->ec != ev->ec)
216      return ECORE_CALLBACK_PASS_ON;
217
218    ec = ev->ec;
219    switch (e_client_visibility_get(ec))
220      {
221       case E_VISIBILITY_FULLY_OBSCURED:
222          evas_object_hide(ec->frame);
223          break;
224       default:
225       case E_VISIBILITY_UNOBSCURED:
226          evas_object_show(ec->frame);
227          break;
228      }
229
230    return ECORE_CALLBACK_PASS_ON;
231 }
232
233 static void
234 _e_comp_wl_video_object_handle_topmost_visibility_follow(struct wl_client *client,
235                                                      struct wl_resource *resource)
236 {
237    E_Video_Object *vo;
238
239    vo = wl_resource_get_user_data(resource);
240
241    if(!vo->ec)
242      return;
243
244    VIN("set follow_topmost_visibility", vo->ec);
245
246    e_client_video_topmost_visibility_follow(vo->ec);
247
248    if (!vo->client_event_handler.visibility_change)
249      {
250         vo->client_event_handler.visibility_change =
251            ecore_event_handler_add(E_EVENT_CLIENT_VISIBILITY_CHANGE,
252                                    (Ecore_Event_Handler_Cb)_e_comp_wl_video_object_ec_cb_visibility_change,
253                                    vo);
254      }
255 }
256
257 static void
258 _e_comp_wl_video_object_handle_topmost_visibility_unfollow(struct wl_client *client,
259                                                        struct wl_resource *resource)
260 {
261    E_Video_Object *vo;
262
263    vo = wl_resource_get_user_data(resource);
264
265    if(!vo->ec)
266      return;
267
268    VIN("set unfollow_topmost_visibility", vo->ec);
269
270    e_client_video_topmost_visibility_unfollow(vo->ec);
271    E_FREE_FUNC(vo->client_event_handler.visibility_change, ecore_event_handler_del);
272 }
273
274 static void
275 _e_comp_wl_video_object_handle_attribute_allowed(struct wl_client *client,
276                                              struct wl_resource *resource)
277 {
278    E_Video_Object *vo;
279
280    vo = wl_resource_get_user_data(resource);
281
282    if(!vo->ec)
283      return;
284
285    VIN("set allowed_attribute", vo->ec);
286    e_client_video_property_allow(vo->ec);
287 }
288
289 static void
290 _e_comp_wl_video_object_handle_attribute_disallowed(struct wl_client *client,
291                                                 struct wl_resource *resource)
292 {
293    E_Video_Object *vo;
294
295    vo = wl_resource_get_user_data(resource);
296
297    if(!vo->ec)
298      return;
299
300    VIN("set disallowed_attribute", vo->ec);
301    e_client_video_property_disallow(vo->ec);
302 }
303
304 static const struct tizen_video_object_interface _e_comp_wl_video_object_implementation =
305 {
306    _e_comp_wl_video_object_handle_destroy,
307    _e_comp_wl_video_object_handle_attribute_set,
308    _e_comp_wl_video_object_handle_topmost_visibility_follow,
309    _e_comp_wl_video_object_handle_topmost_visibility_unfollow,
310    _e_comp_wl_video_object_handle_attribute_allowed,
311    _e_comp_wl_video_object_handle_attribute_disallowed,
312 };
313
314 static void
315 _e_comp_wl_video_handle_object_get(struct wl_client *client,
316                                struct wl_resource *resource,
317                                uint32_t id,
318                                struct wl_resource *surface)
319 {
320    E_Video_Object *vo;
321    int version;
322    struct wl_resource *res;
323
324    version = wl_resource_get_version(resource);
325    res = wl_resource_create(client, &tizen_video_object_interface, version, id);
326    if (res == NULL)
327      {
328         wl_client_post_no_memory(client);
329         return;
330      }
331
332    if (!(vo = _e_comp_wl_video_object_create(res, surface)))
333      {
334         wl_resource_destroy(res);
335         wl_client_post_no_memory(client);
336         return;
337      }
338
339    wl_resource_set_implementation(res, &_e_comp_wl_video_object_implementation,
340                                   vo, _e_comp_wl_video_object_resource_destroy);
341 }
342
343 static void
344 _e_comp_wl_video_handle_viewport_get(struct wl_client *client,
345                                  struct wl_resource *resource,
346                                  uint32_t id,
347                                  struct wl_resource *surface)
348 {
349    E_Client *ec;
350
351    ec = e_client_from_surface_resource(surface);
352
353    if (!ec->comp_data) return;
354
355    if (ec->comp_data && ec->comp_data->scaler.viewport)
356      {
357         wl_resource_post_error(resource,
358                                TIZEN_VIDEO_ERROR_VIEWPORT_EXISTS,
359                                "a viewport for that subsurface already exists");
360         return;
361      }
362
363    if (!e_comp_wl_viewport_create(resource, id, surface))
364      {
365         ERR("Failed to create viewport for wl_surface@%d",
366             wl_resource_get_id(surface));
367         wl_client_post_no_memory(client);
368         return;
369      }
370 }
371
372 static void
373 _e_comp_wl_video_handle_destroy(struct wl_client *client, struct wl_resource *resource)
374 {
375    wl_resource_destroy(resource);
376 }
377
378 static const struct tizen_video_interface _e_comp_wl_video_implementation =
379 {
380    _e_comp_wl_video_handle_object_get,
381    _e_comp_wl_video_handle_viewport_get,
382    _e_comp_wl_video_handle_destroy,
383 };
384
385 static void
386 _e_comp_wl_tizen_video_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
387 {
388    struct wl_resource *res;
389    const uint32_t *formats = NULL;
390    int i, count = 0;
391
392    if (!(res = wl_resource_create(client, &tizen_video_interface, version, id)))
393      {
394         ERR("Could not create tizen_video_interface resource: %m");
395         wl_client_post_no_memory(client);
396         return;
397      }
398
399    wl_resource_set_implementation(res, &_e_comp_wl_video_implementation, NULL, NULL);
400
401    e_comp_screen_available_video_formats_get(&formats, &count);
402    for (i = 0; i < count; i++)
403      tizen_video_send_format(res, formats[i]);
404 }
405
406 static void
407 _e_comp_wl_video_info_cb_vbuf_print(void *data, const char *log_path)
408 {
409    e_comp_wl_video_buffer_list_print(log_path);
410 }
411
412 static void
413 _e_comp_wl_video_info_cb_video_to_primary(void *data, const char *log_path)
414 {
415    Eina_Bool flag;
416
417    flag = e_video_debug_display_primary_plane_value_get();
418    e_video_debug_display_primary_plane_set(!flag);
419 }
420
421 static void
422 _e_comp_wl_video_info_cb_video_punch(void *data, const char *log_path)
423 {
424    Eina_Bool flag;
425
426    flag = e_video_debug_punch_value_get();
427    e_video_debug_punch_set(!flag);
428 }
429
430 EINTERN Eina_Bool
431 e_comp_wl_video_init(void)
432 {
433    struct wl_global *global;
434
435    if (!e_comp_wl) return EINA_FALSE;
436    if (!e_comp_wl->wl.disp) return EINA_FALSE;
437    if (e_comp->wl_comp_data->video.global) return EINA_TRUE;
438
439    /* try to add tizen_video to wayland globals */
440    global = wl_global_create(e_comp_wl->wl.disp, &tizen_video_interface,
441                              1, NULL, _e_comp_wl_tizen_video_bind);
442    if (!global)
443      {
444         ERR("Could not add tizen_video to wayland globals");
445         return EINA_FALSE;
446      }
447
448    e_comp->wl_comp_data->video.global = global;
449
450    e_comp->wl_comp_data->available_hw_accel.underlay = EINA_TRUE;
451    DBG("enable HW underlay");
452
453    e_comp->wl_comp_data->available_hw_accel.scaler = EINA_TRUE;
454    DBG("enable HW scaler");
455
456    e_info_server_hook_set("vbuf", _e_comp_wl_video_info_cb_vbuf_print, NULL);
457    e_info_server_hook_set("video-to-primary", _e_comp_wl_video_info_cb_video_to_primary, NULL);
458    e_info_server_hook_set("video-punch", _e_comp_wl_video_info_cb_video_punch, NULL);
459
460    return EINA_TRUE;
461 }
462
463 EINTERN void
464 e_comp_wl_video_shutdown(void)
465 {
466    e_comp->wl_comp_data->available_hw_accel.underlay = EINA_FALSE;
467    e_comp->wl_comp_data->available_hw_accel.scaler = EINA_FALSE;
468
469    E_FREE_FUNC(e_comp->wl_comp_data->video.global, wl_global_destroy);
470
471    e_info_server_hook_set("vbuf", NULL, NULL);
472    e_info_server_hook_set("video-to-primary", NULL, NULL);
473    e_info_server_hook_set("video-punch", NULL, NULL);
474 }