4 #include <wayland-server.h>
5 #include <eom-server-protocol.h>
7 #include <libds/surface.h>
8 #include <libds-tizen/eom.h>
12 struct wl_global *global;
13 struct wl_list outputs;
14 struct wl_list clients;
16 struct wl_listener destroy;
19 struct wl_signal destroy;
20 struct wl_signal set_attribute;
21 struct wl_signal set_shell_window;
22 struct wl_signal client_destroy;
28 struct ds_tizen_eom_output {
29 struct ds_tizen_eom *eom;
31 int32_t width, height;
32 int32_t physical_width, physical_height; //unit : mm
33 enum ds_tizen_eom_type type;
34 enum ds_tizen_eom_mode mode;
35 enum ds_tizen_eom_status status;
36 enum ds_tizen_eom_attribute attribute;
37 struct wl_list link; // ds_tizen_screenshooter::outputs
40 struct ds_tizen_eom_client {
41 struct ds_tizen_eom *eom;
42 struct wl_resource *res;
43 struct wl_client *client;
44 enum ds_tizen_eom_attribute attribute;
45 enum ds_tizen_eom_attribute_state attribute_state;
46 struct wl_list link; // ds_tizen_screenshooter::clients
49 #define TIZEN_EOM_VERSION 1
52 _ds_tizen_eom_handle_display_destroy(struct wl_listener *listener, void *data);
54 _ds_tizen_eom_bind(struct wl_client *wl_client, void *data, uint32_t version, uint32_t id);
57 _ds_tizen_eom_get_tizen_eom_error(enum ds_tizen_eom_error error)
59 if (error == DS_TIZEN_EOM_ERROR_NONE)
60 return WL_EOM_ERROR_NONE;
61 else if (error == DS_TIZEN_EOM_ERROR_NO_OUTPUT)
62 return WL_EOM_ERROR_NO_OUTPUT;
63 else if (error == DS_TIZEN_EOM_ERROR_NO_ATTRIBUTE)
64 return WL_EOM_ERROR_NO_ATTRIBUTE;
65 else //if (error == DS_TIZEN_EOM_ERROR_OUTPUT_OCCUPIED)
66 return WL_EOM_ERROR_OUTPUT_OCCUPIED;
70 _ds_tizen_eom_get_eom_type(enum ds_tizen_eom_type type)
72 if (type == DS_TIZEN_EOM_OUTPUT_TYPE_NONE)
73 return WL_EOM_TYPE_NONE;
74 else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_VGA)
75 return WL_EOM_TYPE_VGA;
76 else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_DVII)
77 return WL_EOM_TYPE_DVII;
78 else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_DVID)
79 return WL_EOM_TYPE_DVID;
80 else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_DVIA)
81 return WL_EOM_TYPE_DVIA;
82 else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_COMPOSITE)
83 return WL_EOM_TYPE_COMPOSITE;
84 else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_SVIDEO)
85 return WL_EOM_TYPE_SVIDEO;
86 else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_LVDS)
87 return WL_EOM_TYPE_LVDS;
88 else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_COMPONENT)
89 return WL_EOM_TYPE_COMPONENT;
90 else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_9PINDIN)
91 return WL_EOM_TYPE_9PINDIN;
92 else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_DISPLAYPORT)
93 return WL_EOM_TYPE_DISPLAYPORT;
94 else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_HDMIA)
95 return WL_EOM_TYPE_HDMIA;
96 else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_HDMIB)
97 return WL_EOM_TYPE_HDMIB;
98 else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_TV)
99 return WL_EOM_TYPE_TV;
100 else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_EDP)
101 return WL_EOM_TYPE_EDP;
102 else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_VIRTUAL)
103 return WL_EOM_TYPE_VIRTUAL;
104 else //if (type == DS_TIZEN_EOM_OUTPUT_TYPE_DSI)
105 return WL_EOM_TYPE_DSI;
109 _ds_tizen_eom_get_eom_status(enum ds_tizen_eom_status status)
111 if (status == DS_TIZEN_EOM_STATUS_NONE)
112 return WL_EOM_STATUS_NONE;
113 else if (status == DS_TIZEN_EOM_STATUS_CONNECTION)
114 return WL_EOM_STATUS_CONNECTION;
115 else //if (status == DS_TIZEN_EOM_STATUS_DISCONNECTION)
116 return WL_EOM_STATUS_DISCONNECTION;
120 _ds_tizen_eom_get_eom_mode(enum ds_tizen_eom_mode mode)
122 if (mode == DS_TIZEN_EOM_MODE_NONE)
123 return WL_EOM_MODE_NONE;
124 else if (mode == DS_TIZEN_EOM_MODE_MIRROR)
125 return WL_EOM_MODE_MIRROR;
126 else //if (mode == DS_TIZEN_EOM_MODE_PRESENTATION)
127 return WL_EOM_MODE_PRESENTATION;
131 _ds_tizen_eom_get_eom_attribute(enum ds_tizen_eom_attribute attribute)
133 if (attribute == DS_TIZEN_EOM_ATTRIBUTE_NONE)
134 return WL_EOM_ATTRIBUTE_NONE;
135 else if (attribute == DS_TIZEN_EOM_ATTRIBUTE_NORMAL)
136 return WL_EOM_ATTRIBUTE_NORMAL;
137 else if (attribute == DS_TIZEN_EOM_ATTRIBUTE_EXCLUSIVE_SHARE)
138 return WL_EOM_ATTRIBUTE_EXCLUSIVE_SHARE;
139 else //if (attribute == DS_TIZEN_EOM_ATTRIBUTE_EXCLUSIVE)
140 return WL_EOM_ATTRIBUTE_EXCLUSIVE;
144 _ds_tizen_eom_get_eom_attribute_state(enum ds_tizen_eom_attribute_state attribute_state)
146 if (attribute_state == DS_TIZEN_EOM_ATTRIBUTE_STATE_NONE)
147 return WL_EOM_ATTRIBUTE_STATE_NONE;
148 else if (attribute_state == DS_TIZEN_EOM_ATTRIBUTE_STATE_ACTIVE)
149 return WL_EOM_ATTRIBUTE_STATE_ACTIVE;
150 else if (attribute_state == DS_TIZEN_EOM_ATTRIBUTE_STATE_INACTIVE)
151 return WL_EOM_ATTRIBUTE_STATE_INACTIVE;
152 else //if (attribute_state == DS_TIZEN_EOM_ATTRIBUTE_STATE_LOST)
153 return WL_EOM_ATTRIBUTE_STATE_LOST;
156 static enum ds_tizen_eom_attribute
157 _ds_tizen_eom_get_ds_eom_attribute(uint32_t attribute)
159 if (attribute == WL_EOM_ATTRIBUTE_NONE)
160 return DS_TIZEN_EOM_ATTRIBUTE_NONE;
161 else if (attribute == WL_EOM_ATTRIBUTE_NORMAL)
162 return DS_TIZEN_EOM_ATTRIBUTE_NORMAL;
163 else if (attribute == WL_EOM_ATTRIBUTE_EXCLUSIVE_SHARE)
164 return DS_TIZEN_EOM_ATTRIBUTE_EXCLUSIVE_SHARE;
165 else //if (attribute == WL_EOM_ATTRIBUTE_EXCLUSIVE)
166 return DS_TIZEN_EOM_ATTRIBUTE_EXCLUSIVE;
170 _ds_tizen_eom_check_valid_output(struct ds_tizen_eom *eom, struct ds_tizen_eom_output *output)
172 struct ds_tizen_eom_output *output_tmp;
177 wl_list_for_each(output_tmp, &eom->outputs, link) {
178 if (output_tmp == output)
186 _ds_tizen_eom_check_valid_client(struct ds_tizen_eom *eom, struct ds_tizen_eom_client *client)
188 struct ds_tizen_eom_client *client_tmp;
193 wl_list_for_each(client_tmp, &eom->clients, link) {
194 if (client_tmp == client)
201 WL_EXPORT struct ds_tizen_eom *
202 ds_tizen_eom_create(struct wl_display *display)
204 struct ds_tizen_eom *eom;
206 eom = calloc(1, sizeof *eom);
208 ds_err("eom create fail : memory alloc failed");
212 eom->global = wl_global_create(display, &wl_eom_interface, 1, eom, _ds_tizen_eom_bind);
214 ds_err("global create fail : wl_eom_interface failed");
219 wl_list_init(&eom->outputs);
220 wl_list_init(&eom->clients);
222 wl_signal_init(&eom->events.destroy);
223 wl_signal_init(&eom->events.set_attribute);
224 wl_signal_init(&eom->events.set_shell_window);
225 wl_signal_init(&eom->events.client_destroy);
227 eom->destroy.notify = _ds_tizen_eom_handle_display_destroy;
228 wl_display_add_destroy_listener(display, &eom->destroy);
230 ds_inf("global create : eom(%p)", eom);
236 WL_EXPORT struct ds_tizen_eom_output *
237 ds_tizen_eom_create_output(struct ds_tizen_eom *eom, int id,
238 int width, int height, int physical_width, int pyhsical_height,
239 enum ds_tizen_eom_type type)
241 struct ds_tizen_eom_output *output;
243 wl_list_for_each(output, &eom->outputs, link) {
244 if (output->id == id) {
245 ds_err("output create fail : already exist same id output");
250 output = calloc(1, sizeof *output);
252 ds_err("output create fail : memory alloc failed");
258 output->width = width;
259 output->height = height;
260 output->physical_width = physical_width;
261 output->physical_height = pyhsical_height;
264 wl_list_insert(&eom->outputs, &output->link);
270 ds_tizen_eom_destroy_output(struct ds_tizen_eom_output *output)
272 struct ds_tizen_eom *eom;
275 if (_ds_tizen_eom_check_valid_output(eom, output) == false)
278 wl_list_remove(&output->link);
283 ds_tizen_eom_get_output_resolution(struct ds_tizen_eom_output *output,
284 int *width, int *height)
289 *width = output->width;
290 *height = output->height;
294 ds_tizen_eom_get_output_physical_resolution(struct ds_tizen_eom_output *output,
295 int *width, int *height)
300 *width = output->physical_width;
301 *height = output->physical_height;
304 WL_EXPORT enum ds_tizen_eom_type
305 ds_tizen_eom_get_output_type(struct ds_tizen_eom_output *output)
308 return DS_TIZEN_EOM_OUTPUT_TYPE_NONE;
314 ds_tizen_eom_set_output_mode(struct ds_tizen_eom_output *output,
315 enum ds_tizen_eom_mode mode)
323 WL_EXPORT enum ds_tizen_eom_mode
324 ds_tizen_eom_get_output_mode(struct ds_tizen_eom_output *output)
327 return DS_TIZEN_EOM_MODE_NONE;
333 ds_tizen_eom_set_output_status(struct ds_tizen_eom_output *output,
334 enum ds_tizen_eom_status status)
339 output->status = status;
342 WL_EXPORT enum ds_tizen_eom_status
343 ds_tizen_eom_get_output_status(struct ds_tizen_eom_output *output)
346 return DS_TIZEN_EOM_STATUS_NONE;
348 return output->status;
352 ds_tizen_eom_set_output_attribute(struct ds_tizen_eom_output *output,
353 enum ds_tizen_eom_attribute attribute)
358 output->attribute = attribute;
361 WL_EXPORT enum ds_tizen_eom_attribute
362 ds_tizen_eom_get_output_attribute(struct ds_tizen_eom_output *output)
365 return DS_TIZEN_EOM_ATTRIBUTE_NONE;
367 return output->attribute;
371 ds_tizen_eom_set_client_attribute(struct ds_tizen_eom_client *client,
372 enum ds_tizen_eom_attribute attribute)
377 client->attribute = attribute;
380 WL_EXPORT enum ds_tizen_eom_attribute
381 ds_tizen_eom_get_client_attribute(struct ds_tizen_eom_client *client)
384 return DS_TIZEN_EOM_ATTRIBUTE_NONE;
386 return client->attribute;
390 ds_tizen_eom_set_client_attribute_state(struct ds_tizen_eom_client *client,
391 enum ds_tizen_eom_attribute_state attribute_state)
396 client->attribute_state = attribute_state;
399 WL_EXPORT enum ds_tizen_eom_attribute_state
400 ds_tizen_eom_get_client_attribute_state(struct ds_tizen_eom_client *client)
403 return DS_TIZEN_EOM_ATTRIBUTE_STATE_NONE;
405 return client->attribute_state;
409 ds_tizen_eom_add_destroy_listener(struct ds_tizen_eom *eom,
410 struct wl_listener *listener)
412 wl_signal_add(&eom->events.destroy, listener);
416 ds_tizen_eom_add_set_attribute_listener(struct ds_tizen_eom *eom,
417 struct wl_listener *listener)
419 wl_signal_add(&eom->events.set_attribute, listener);
423 ds_tizen_eom_add_set_shell_window_listener(struct ds_tizen_eom *eom,
424 struct wl_listener *listener)
426 wl_signal_add(&eom->events.set_shell_window, listener);
430 ds_tizen_eom_add_client_destroy_listener(struct ds_tizen_eom *eom,
431 struct wl_listener *listener)
433 wl_signal_add(&eom->events.client_destroy, listener);
437 ds_tizen_eom_send_output_info(struct ds_tizen_eom *eom,
438 struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output,
439 enum ds_tizen_eom_error error)
441 if (_ds_tizen_eom_check_valid_output(eom, output) == false) {
442 ds_err("invalid output parameter");
446 if (_ds_tizen_eom_check_valid_client(eom, client) == false) {
447 ds_err("invalid client parameter");
451 wl_eom_send_output_info(client->res, output->id,
452 _ds_tizen_eom_get_eom_type(output->type),
453 _ds_tizen_eom_get_eom_mode(output->mode),
454 output->width, output->height, output->physical_width, output->physical_height,
455 _ds_tizen_eom_get_eom_status(output->status), 1, 0, 0, 0);
457 ds_inf("send_output_info - id:%d, type:%d, mode:%d, conn:%d, w:%d, h:%d, w_mm:%d, h_mm:%d",
458 output->id, output->type, output->mode, output->status,
459 output->width, output->height, output->physical_width, output->physical_height);
464 ds_tizen_eom_send_output_type(struct ds_tizen_eom *eom,
465 struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output)
467 if (_ds_tizen_eom_check_valid_output(eom, output) == false) {
468 ds_err("invalid output parameter");
472 if (_ds_tizen_eom_check_valid_client(eom, client) == false) {
473 ds_err("invalid client parameter");
477 wl_eom_send_output_type(client->res, output->id,
478 _ds_tizen_eom_get_eom_type(output->type),
479 _ds_tizen_eom_get_eom_status(output->status));
483 ds_tizen_eom_send_output_mode(struct ds_tizen_eom *eom,
484 struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output)
486 if (_ds_tizen_eom_check_valid_output(eom, output) == false) {
487 ds_err("invalid output parameter");
491 if (_ds_tizen_eom_check_valid_client(eom, client) == false) {
492 ds_err("invalid client parameter");
496 wl_eom_send_output_mode(client->res, output->id,
497 _ds_tizen_eom_get_eom_mode(output->mode));
501 ds_tizen_eom_send_output_attribute(struct ds_tizen_eom *eom,
502 struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output,
503 enum ds_tizen_eom_error error)
505 if (_ds_tizen_eom_check_valid_output(eom, output) == false) {
506 ds_err("invalid output parameter");
510 if (_ds_tizen_eom_check_valid_client(eom, client) == false) {
511 ds_err("invalid client parameter");
515 wl_eom_send_output_attribute(client->res, output->id,
516 _ds_tizen_eom_get_eom_attribute(output->attribute),
517 _ds_tizen_eom_get_eom_attribute_state(client->attribute_state),
518 _ds_tizen_eom_get_tizen_eom_error(error));
522 ds_tizen_eom_send_output_set_window(struct ds_tizen_eom *eom,
523 struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output,
524 enum ds_tizen_eom_error error)
526 if (_ds_tizen_eom_check_valid_output(eom, output) == false) {
527 ds_err("invalid output parameter");
531 if (_ds_tizen_eom_check_valid_client(eom, client) == false) {
532 ds_err("invalid client parameter");
536 wl_eom_send_output_set_window(client->res, output->id,
537 _ds_tizen_eom_get_tizen_eom_error(error));
541 _ds_tizen_eom_handle_display_destroy(struct wl_listener *listener, void *data)
543 struct ds_tizen_eom *eom;
544 struct ds_tizen_eom_output *output, *tmp;
546 eom = wl_container_of(listener, eom, destroy);
548 ds_inf("global destroy : eom(%p)", eom);
550 wl_signal_emit_mutable(&eom->events.destroy, eom);
551 wl_list_remove(&eom->destroy.link);
552 wl_global_destroy(eom->global);
554 wl_list_for_each_safe(output, tmp, &eom->outputs, link) {
555 wl_list_remove(&output->link);
561 static struct ds_tizen_eom_output *
562 _ds_tizen_eom_get_eom_output_by_id(struct ds_tizen_eom *eom, uint32_t id)
564 struct ds_tizen_eom_output *output;
566 wl_list_for_each(output, &eom->outputs, link) {
567 if ((uint32_t)output->id == id)
575 _ds_tizen_eom_handle_set_attribute(struct wl_client *client,
576 struct wl_resource *resource, uint32_t output_id, uint32_t attribute)
578 struct ds_tizen_eom *eom;
579 struct ds_tizen_eom_output *output;
580 struct ds_tizen_eom_client *eom_client;
581 enum ds_tizen_eom_attribute eom_attribute;
583 eom_client = wl_resource_get_user_data(resource);
584 if (attribute > WL_EOM_ATTRIBUTE_EXCLUSIVE) {
585 ds_err("set attribute error : not supported attribute(%d)", attribute);
589 eom = eom_client->eom;
590 output = _ds_tizen_eom_get_eom_output_by_id(eom, output_id);
591 if (output == NULL) {
592 ds_err("set attribute error : no eom output id(%d)", output_id);
596 eom_attribute = _ds_tizen_eom_get_ds_eom_attribute(attribute);
598 struct ds_tizen_eom_event_set_attribute event = {
600 .client = eom_client,
601 .attribute = eom_attribute,
604 wl_signal_emit_mutable(&eom->events.set_attribute, &event);
608 _ds_tizen_eom_handle_set_shell_window(struct wl_client *client,
609 struct wl_resource *resource, uint32_t output_id, struct wl_resource *surface_resource)
611 struct ds_tizen_eom *eom;
612 struct ds_tizen_eom_output *output;
613 struct ds_tizen_eom_client *eom_client;
614 struct ds_surface *surface;
616 eom_client = wl_resource_get_user_data(resource);
618 eom = eom_client->eom;
619 output = _ds_tizen_eom_get_eom_output_by_id(eom, output_id);
620 if (output == NULL) {
621 ds_err("set attribute error : no eom output id(%d)", output_id);
625 surface = ds_surface_from_resource(surface_resource);
627 struct ds_tizen_eom_event_set_shell_window event = {
629 .client = eom_client,
633 wl_signal_emit_mutable(&eom->events.set_shell_window, &event);
637 _ds_tizen_eom_handle_get_output_info(struct wl_client *client,
638 struct wl_resource *resource, uint32_t output_id)
640 struct ds_tizen_eom *eom;
641 struct ds_tizen_eom_output *output;
642 struct ds_tizen_eom_client *eom_client;
644 eom_client = wl_resource_get_user_data(resource);
645 eom = eom_client->eom;
646 output = _ds_tizen_eom_get_eom_output_by_id(eom, output_id);
647 if (output == NULL) {
648 ds_err("get output info error : no eom output id(%d)", output_id);
652 wl_eom_send_output_info(eom_client->res, output->id,
653 _ds_tizen_eom_get_eom_type(output->type),
654 _ds_tizen_eom_get_eom_mode(output->mode),
655 output->width, output->height, output->physical_width, output->physical_height,
656 _ds_tizen_eom_get_eom_status(output->status), 1, 0, 0, 0);
658 ds_inf("get_output_info - id:%d, type:%d, mode:%d, conn:%d, w:%d, h:%d, w_mm:%d, h_mm:%d",
659 output->id, output->type, output->mode, output->status,
660 output->width, output->height, output->physical_width, output->physical_height);
664 _ds_tizen_eom_handle_destroy(struct wl_client *client, struct wl_resource *resource)
666 wl_resource_destroy(resource);
669 static const struct wl_eom_interface eom_impl =
671 _ds_tizen_eom_handle_set_attribute,
672 _ds_tizen_eom_handle_set_shell_window,
673 _ds_tizen_eom_handle_get_output_info,
674 // _ds_tizen_eom_handle_destroy,
678 _ds_tizen_eom_client_cb_destroy(struct wl_resource *resource)
680 struct ds_tizen_eom_client *eom_client;
682 ds_inf("_ds_tizen_eom_client_cb_destroy (res:%p)", resource);
684 eom_client = wl_resource_get_user_data(resource);
686 wl_signal_emit_mutable(&eom_client->eom->events.client_destroy, eom_client);
687 wl_list_remove(&eom_client->link);
692 _ds_tizen_eom_bind(struct wl_client *client, void *data, uint32_t version,
695 struct ds_tizen_eom *eom = data;
696 struct ds_tizen_eom_client *eom_client;
697 struct ds_tizen_eom_output *output;
699 eom_client = calloc(1, sizeof *eom_client);
700 if (eom_client == NULL) {
701 wl_client_post_no_memory(client);
705 eom_client->eom = eom;
706 eom_client->client = client;
708 eom_client->res = wl_resource_create(client, &wl_eom_interface,
709 MIN(version, TIZEN_EOM_VERSION), id);
710 if (eom_client->res == NULL) {
711 ds_err("eom bind error : wl_resource_create failed.");
712 wl_client_post_no_memory(client);
717 wl_resource_set_implementation(eom_client->res, &eom_impl,
718 eom_client, _ds_tizen_eom_client_cb_destroy);
720 wl_eom_send_output_count(eom_client->res, eom->output_count);
722 wl_list_for_each(output, &eom->outputs, link) {
723 wl_eom_send_output_info(eom_client->res, output->id,
724 _ds_tizen_eom_get_eom_type(output->type),
725 _ds_tizen_eom_get_eom_mode(output->mode),
726 output->width, output->height, output->physical_width, output->physical_height,
727 _ds_tizen_eom_get_eom_status(output->status), 1, 0, 0, 0);
730 wl_list_insert(&eom->clients, &eom_client->link);