--- /dev/null
+#ifndef LIBDS_EOM_H
+#define LIBDS_EOM_H
+
+#include <stdint.h>
+#include <wayland-server.h>
+#include <libds/output.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ds_tizen_eom;
+struct ds_tizen_eom_output;
+struct ds_tizen_eom_client;
+
+enum ds_tizen_eom_error {
+ DS_TIZEN_EOM_ERROR_NONE,
+ DS_TIZEN_EOM_ERROR_NO_OUTPUT,
+ DS_TIZEN_EOM_ERROR_NO_ATTRIBUTE,
+ DS_TIZEN_EOM_ERROR_OUTPUT_OCCUPIED,
+};
+
+enum ds_tizen_eom_type {
+ DS_TIZEN_EOM_OUTPUT_TYPE_NONE, /**< Unknown output type */
+ DS_TIZEN_EOM_OUTPUT_TYPE_VGA, /**< VGA output */
+ DS_TIZEN_EOM_OUTPUT_TYPE_DVII, /**< DVII output type */
+ DS_TIZEN_EOM_OUTPUT_TYPE_DVID, /**< DVID output type */
+ DS_TIZEN_EOM_OUTPUT_TYPE_DVIA, /**< DVIA output type */
+ DS_TIZEN_EOM_OUTPUT_TYPE_COMPOSITE, /**< Composite output type */
+ DS_TIZEN_EOM_OUTPUT_TYPE_SVIDEO, /**< SVIDEO output type */
+ DS_TIZEN_EOM_OUTPUT_TYPE_LVDS, /**< LVDS output type */
+ DS_TIZEN_EOM_OUTPUT_TYPE_COMPONENT, /**< Component output type */
+ DS_TIZEN_EOM_OUTPUT_TYPE_9PINDIN, /**< 9PinDIN output type */
+ DS_TIZEN_EOM_OUTPUT_TYPE_DISPLAYPORT, /**< DisplayPort output type */
+ DS_TIZEN_EOM_OUTPUT_TYPE_HDMIA, /**< HDMIA output type */
+ DS_TIZEN_EOM_OUTPUT_TYPE_HDMIB, /**< HDMIB output type */
+ DS_TIZEN_EOM_OUTPUT_TYPE_TV, /**< TV output type */
+ DS_TIZEN_EOM_OUTPUT_TYPE_EDP, /**< EDP output type */
+ DS_TIZEN_EOM_OUTPUT_TYPE_VIRTUAL, /**< VIRTUAL output type */
+ DS_TIZEN_EOM_OUTPUT_TYPE_DSI, /**< DSI output type */
+ DS_TIZEN_EOM_OUTPUT_TYPE_MAX,
+};
+
+enum ds_tizen_eom_status {
+ DS_TIZEN_EOM_STATUS_NONE,
+ DS_TIZEN_EOM_STATUS_CONNECTION,
+ DS_TIZEN_EOM_STATUS_DISCONNECTION,
+};
+
+enum ds_tizen_eom_mode {
+ DS_TIZEN_EOM_MODE_NONE,
+ DS_TIZEN_EOM_MODE_MIRROR,
+ DS_TIZEN_EOM_MODE_PRESENTATION,
+ DS_TIZEN_EOM_MODE_MAX,
+} eom_output_mode_e;
+
+enum ds_tizen_eom_attribute {
+ DS_TIZEN_EOM_ATTRIBUTE_NONE,
+ DS_TIZEN_EOM_ATTRIBUTE_NORMAL,
+ DS_TIZEN_EOM_ATTRIBUTE_EXCLUSIVE_SHARE,
+ DS_TIZEN_EOM_ATTRIBUTE_EXCLUSIVE,
+ DS_TIZEN_EOM_ATTRIBUTE_MAX,
+};
+
+enum ds_tizen_eom_attribute_state {
+ DS_TIZEN_EOM_ATTRIBUTE_STATE_NONE,
+ DS_TIZEN_EOM_ATTRIBUTE_STATE_ACTIVE,
+ DS_TIZEN_EOM_ATTRIBUTE_STATE_INACTIVE,
+ DS_TIZEN_EOM_ATTRIBUTE_STATE_LOST,
+ DS_TIZEN_EOM_ATTRIBUTE_STATE_MAX,
+};
+
+enum ds_tizen_eom_set_window_error {
+ DS_TIZEN_EOM_SET_WINDOW_ERROR_NONE,
+ DS_TIZEN_EOM_SET_WINDOW_ERROR_NO_OUTPUT,
+ DS_TIZEN_EOM_SET_WINDOW_ERROR_OUTPUT_OCCUPIED,
+};
+
+struct ds_tizen_eom_event_set_attribute {
+ struct ds_tizen_eom_output *output;
+ struct ds_tizen_eom_client *client;
+ enum ds_tizen_eom_attribute attribute;
+};
+
+struct ds_tizen_eom_event_set_shell_window {
+ struct ds_tizen_eom_output *output;
+ struct ds_tizen_eom_client *client;
+ struct ds_surface *surface;
+};
+
+struct ds_tizen_eom *
+ds_tizen_eom_create(struct wl_display *display);
+
+struct ds_tizen_eom_output *
+ds_tizen_eom_create_output(struct ds_tizen_eom *eom, int id,
+ int width, int height, int physical_width, int pyhsical_height,
+ enum ds_tizen_eom_type type);
+
+void
+ds_tizen_eom_destroy_output(struct ds_tizen_eom_output *output);
+
+void
+ds_tizen_eom_get_output_resolution(struct ds_tizen_eom_output *output,
+ int *width, int *height);
+
+void
+ds_tizen_eom_get_output_physical_resolution(struct ds_tizen_eom_output *output,
+ int *width, int *height);
+
+enum ds_tizen_eom_type
+ds_tizen_eom_get_output_type(struct ds_tizen_eom_output *output);
+
+void
+ds_tizen_eom_set_output_mode(struct ds_tizen_eom_output *output,
+ enum ds_tizen_eom_mode mode);
+
+enum ds_tizen_eom_mode
+ds_tizen_eom_get_output_mode(struct ds_tizen_eom_output *output);
+
+void
+ds_tizen_eom_set_output_status(struct ds_tizen_eom_output *output,
+ enum ds_tizen_eom_status status);
+
+enum ds_tizen_eom_status
+ds_tizen_eom_get_output_status(struct ds_tizen_eom_output *output);
+
+void
+ds_tizen_eom_set_output_attribute(struct ds_tizen_eom_output *output,
+ enum ds_tizen_eom_attribute attribute);
+
+enum ds_tizen_eom_attribute
+ds_tizen_eom_get_output_attribute(struct ds_tizen_eom_output *output);
+
+void
+ds_tizen_eom_set_client_attribute(struct ds_tizen_eom_client *client,
+ enum ds_tizen_eom_attribute attribute);
+
+enum ds_tizen_eom_attribute
+ds_tizen_eom_get_client_attribute(struct ds_tizen_eom_client *client);
+
+void
+ds_tizen_eom_set_client_attribute_state(struct ds_tizen_eom_client *client,
+ enum ds_tizen_eom_attribute_state attribute_state);
+
+enum ds_tizen_eom_attribute_state
+ds_tizen_eom_get_client_attribute_state(struct ds_tizen_eom_client *client);
+
+void
+ds_tizen_eom_add_destroy_listener(struct ds_tizen_eom *eom,
+ struct wl_listener *listener);
+
+void
+ds_tizen_eom_add_set_attribute_listener(struct ds_tizen_eom *eom,
+ struct wl_listener *listener);
+
+void
+ds_tizen_eom_add_set_shell_window_listener(struct ds_tizen_eom *eom,
+ struct wl_listener *listener);
+
+void
+ds_tizen_eom_add_client_destroy_listener(struct ds_tizen_eom *eom,
+ struct wl_listener *listener);
+
+void
+ds_tizen_eom_send_output_info(struct ds_tizen_eom *eom,
+ struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output,
+ enum ds_tizen_eom_error error);
+
+void
+ds_tizen_eom_send_output_type(struct ds_tizen_eom *eom,
+ struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output);
+
+void
+ds_tizen_eom_send_output_mode(struct ds_tizen_eom *eom,
+ struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output);
+
+void
+ds_tizen_eom_send_output_attribute(struct ds_tizen_eom *eom,
+ struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output,
+ enum ds_tizen_eom_error error);
+
+void
+ds_tizen_eom_send_output_set_window(struct ds_tizen_eom *eom,
+ struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output,
+ enum ds_tizen_eom_error error);
+
+void
+ds_tizen_eom_send_output_add(struct ds_tizen_eom *eom,
+ struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output);
+
+void
+ds_tizen_eom_send_output_remove(struct ds_tizen_eom *eom,
+ struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <wayland-server.h>
+#include <eom-server-protocol.h>
+#include <libds/log.h>
+#include <libds/surface.h>
+#include <libds-tizen/eom.h>
+#include "util.h"
+
+struct ds_tizen_eom {
+ struct wl_global *global;
+ struct wl_list outputs;
+ struct wl_list clients;
+
+ struct wl_listener destroy;
+
+ struct {
+ struct wl_signal destroy;
+ struct wl_signal set_attribute;
+ struct wl_signal set_shell_window;
+ struct wl_signal client_destroy;
+ } events;
+
+ int32_t output_count;
+};
+
+struct ds_tizen_eom_output {
+ struct ds_tizen_eom *eom;
+ int32_t id;
+ int32_t width, height;
+ int32_t physical_width, physical_height; //unit : mm
+ enum ds_tizen_eom_type type;
+ enum ds_tizen_eom_mode mode;
+ enum ds_tizen_eom_status status;
+ enum ds_tizen_eom_attribute attribute;
+ struct wl_list link; // ds_tizen_screenshooter::outputs
+};
+
+struct ds_tizen_eom_client {
+ struct ds_tizen_eom *eom;
+ struct wl_resource *res;
+ struct wl_client *client;
+ enum ds_tizen_eom_attribute attribute;
+ enum ds_tizen_eom_attribute_state attribute_state;
+ struct wl_list link; // ds_tizen_screenshooter::clients
+};
+
+#define TIZEN_EOM_VERSION 1
+
+static void
+_ds_tizen_eom_handle_display_destroy(struct wl_listener *listener, void *data);
+static void
+_ds_tizen_eom_bind(struct wl_client *wl_client, void *data, uint32_t version, uint32_t id);
+
+static uint32_t
+_ds_tizen_eom_get_tizen_eom_error(enum ds_tizen_eom_error error)
+{
+ if (error == DS_TIZEN_EOM_ERROR_NONE)
+ return WL_EOM_ERROR_NONE;
+ else if (error == DS_TIZEN_EOM_ERROR_NO_OUTPUT)
+ return WL_EOM_ERROR_NO_OUTPUT;
+ else if (error == DS_TIZEN_EOM_ERROR_NO_ATTRIBUTE)
+ return WL_EOM_ERROR_NO_ATTRIBUTE;
+ else //if (error == DS_TIZEN_EOM_ERROR_OUTPUT_OCCUPIED)
+ return WL_EOM_ERROR_OUTPUT_OCCUPIED;
+}
+
+static uint32_t
+_ds_tizen_eom_get_eom_type(enum ds_tizen_eom_type type)
+{
+ if (type == DS_TIZEN_EOM_OUTPUT_TYPE_NONE)
+ return WL_EOM_TYPE_NONE;
+ else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_VGA)
+ return WL_EOM_TYPE_VGA;
+ else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_DVII)
+ return WL_EOM_TYPE_DVII;
+ else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_DVID)
+ return WL_EOM_TYPE_DVID;
+ else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_DVIA)
+ return WL_EOM_TYPE_DVIA;
+ else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_COMPOSITE)
+ return WL_EOM_TYPE_COMPOSITE;
+ else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_SVIDEO)
+ return WL_EOM_TYPE_SVIDEO;
+ else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_LVDS)
+ return WL_EOM_TYPE_LVDS;
+ else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_COMPONENT)
+ return WL_EOM_TYPE_COMPONENT;
+ else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_9PINDIN)
+ return WL_EOM_TYPE_9PINDIN;
+ else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_DISPLAYPORT)
+ return WL_EOM_TYPE_DISPLAYPORT;
+ else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_HDMIA)
+ return WL_EOM_TYPE_HDMIA;
+ else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_HDMIB)
+ return WL_EOM_TYPE_HDMIB;
+ else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_TV)
+ return WL_EOM_TYPE_TV;
+ else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_EDP)
+ return WL_EOM_TYPE_EDP;
+ else if (type == DS_TIZEN_EOM_OUTPUT_TYPE_VIRTUAL)
+ return WL_EOM_TYPE_VIRTUAL;
+ else //if (type == DS_TIZEN_EOM_OUTPUT_TYPE_DSI)
+ return WL_EOM_TYPE_DSI;
+}
+
+static uint32_t
+_ds_tizen_eom_get_eom_status(enum ds_tizen_eom_status status)
+{
+ if (status == DS_TIZEN_EOM_STATUS_NONE)
+ return WL_EOM_STATUS_NONE;
+ else if (status == DS_TIZEN_EOM_STATUS_CONNECTION)
+ return WL_EOM_STATUS_CONNECTION;
+ else //if (status == DS_TIZEN_EOM_STATUS_DISCONNECTION)
+ return WL_EOM_STATUS_DISCONNECTION;
+}
+
+static uint32_t
+_ds_tizen_eom_get_eom_mode(enum ds_tizen_eom_mode mode)
+{
+ if (mode == DS_TIZEN_EOM_MODE_NONE)
+ return WL_EOM_MODE_NONE;
+ else if (mode == DS_TIZEN_EOM_MODE_MIRROR)
+ return WL_EOM_MODE_MIRROR;
+ else //if (mode == DS_TIZEN_EOM_MODE_PRESENTATION)
+ return WL_EOM_MODE_PRESENTATION;
+}
+
+static uint32_t
+_ds_tizen_eom_get_eom_attribute(enum ds_tizen_eom_attribute attribute)
+{
+ if (attribute == DS_TIZEN_EOM_ATTRIBUTE_NONE)
+ return WL_EOM_ATTRIBUTE_NONE;
+ else if (attribute == DS_TIZEN_EOM_ATTRIBUTE_NORMAL)
+ return WL_EOM_ATTRIBUTE_NORMAL;
+ else if (attribute == DS_TIZEN_EOM_ATTRIBUTE_EXCLUSIVE_SHARE)
+ return WL_EOM_ATTRIBUTE_EXCLUSIVE_SHARE;
+ else //if (attribute == DS_TIZEN_EOM_ATTRIBUTE_EXCLUSIVE)
+ return WL_EOM_ATTRIBUTE_EXCLUSIVE;
+}
+
+static uint32_t
+_ds_tizen_eom_get_eom_attribute_state(enum ds_tizen_eom_attribute_state attribute_state)
+{
+ if (attribute_state == DS_TIZEN_EOM_ATTRIBUTE_STATE_NONE)
+ return WL_EOM_ATTRIBUTE_STATE_NONE;
+ else if (attribute_state == DS_TIZEN_EOM_ATTRIBUTE_STATE_ACTIVE)
+ return WL_EOM_ATTRIBUTE_STATE_ACTIVE;
+ else if (attribute_state == DS_TIZEN_EOM_ATTRIBUTE_STATE_INACTIVE)
+ return WL_EOM_ATTRIBUTE_STATE_INACTIVE;
+ else //if (attribute_state == DS_TIZEN_EOM_ATTRIBUTE_STATE_LOST)
+ return WL_EOM_ATTRIBUTE_STATE_LOST;
+}
+
+static enum ds_tizen_eom_attribute
+_ds_tizen_eom_get_ds_eom_attribute(uint32_t attribute)
+{
+ if (attribute == WL_EOM_ATTRIBUTE_NONE)
+ return DS_TIZEN_EOM_ATTRIBUTE_NONE;
+ else if (attribute == WL_EOM_ATTRIBUTE_NORMAL)
+ return DS_TIZEN_EOM_ATTRIBUTE_NORMAL;
+ else if (attribute == WL_EOM_ATTRIBUTE_EXCLUSIVE_SHARE)
+ return DS_TIZEN_EOM_ATTRIBUTE_EXCLUSIVE_SHARE;
+ else //if (attribute == WL_EOM_ATTRIBUTE_EXCLUSIVE)
+ return DS_TIZEN_EOM_ATTRIBUTE_EXCLUSIVE;
+}
+
+static bool
+_ds_tizen_eom_check_valid_output(struct ds_tizen_eom *eom, struct ds_tizen_eom_output *output)
+{
+ struct ds_tizen_eom_output *output_tmp;
+
+ if (output == NULL)
+ return false;
+
+ wl_list_for_each(output_tmp, &eom->outputs, link) {
+ if (output_tmp == output)
+ return true;
+ }
+
+ return false;
+}
+
+static bool
+_ds_tizen_eom_check_valid_client(struct ds_tizen_eom *eom, struct ds_tizen_eom_client *client)
+{
+ struct ds_tizen_eom_client *client_tmp;
+
+ if (client == NULL)
+ return false;
+
+ wl_list_for_each(client_tmp, &eom->clients, link) {
+ if (client_tmp == client)
+ return true;
+ }
+
+ return false;
+}
+
+WL_EXPORT struct ds_tizen_eom *
+ds_tizen_eom_create(struct wl_display *display)
+{
+ struct ds_tizen_eom *eom;
+
+ eom = calloc(1, sizeof *eom);
+ if (!eom) {
+ ds_err("eom create fail : memory alloc failed");
+ return NULL;
+ }
+
+ eom->global = wl_global_create(display, &wl_eom_interface, 1, eom, _ds_tizen_eom_bind);
+ if (!eom->global) {
+ ds_err("global create fail : wl_eom_interface failed");
+ free(eom);
+ return NULL;
+ }
+
+ wl_list_init(&eom->outputs);
+ wl_list_init(&eom->clients);
+
+ wl_signal_init(&eom->events.destroy);
+ wl_signal_init(&eom->events.set_attribute);
+ wl_signal_init(&eom->events.set_shell_window);
+ wl_signal_init(&eom->events.client_destroy);
+
+ eom->destroy.notify = _ds_tizen_eom_handle_display_destroy;
+ wl_display_add_destroy_listener(display, &eom->destroy);
+
+ ds_inf("global create : eom(%p)", eom);
+
+ return eom;
+
+}
+
+WL_EXPORT struct ds_tizen_eom_output *
+ds_tizen_eom_create_output(struct ds_tizen_eom *eom, int id,
+ int width, int height, int physical_width, int pyhsical_height,
+ enum ds_tizen_eom_type type)
+{
+ struct ds_tizen_eom_output *output;
+
+ wl_list_for_each(output, &eom->outputs, link) {
+ if (output->id == id) {
+ ds_err("output create fail : already exist same id output");
+ return NULL;
+ }
+ }
+
+ output = calloc(1, sizeof *output);
+ if (!output) {
+ ds_err("output create fail : memory alloc failed");
+ return NULL;
+ }
+
+ output->eom = eom;
+ output->id = id;
+ output->width = width;
+ output->height = height;
+ output->physical_width = physical_width;
+ output->physical_height = pyhsical_height;
+ output->type = type;
+
+ wl_list_insert(&eom->outputs, &output->link);
+
+ return output;
+}
+
+WL_EXPORT void
+ds_tizen_eom_destroy_output(struct ds_tizen_eom_output *output)
+{
+ struct ds_tizen_eom *eom;
+
+ eom = output->eom;
+ if (_ds_tizen_eom_check_valid_output(eom, output) == false)
+ return;
+
+ wl_list_remove(&output->link);
+ free(output);
+}
+
+WL_EXPORT void
+ds_tizen_eom_get_output_resolution(struct ds_tizen_eom_output *output,
+ int *width, int *height)
+{
+ if (output == NULL)
+ return;
+
+ *width = output->width;
+ *height = output->height;
+}
+
+WL_EXPORT void
+ds_tizen_eom_get_output_physical_resolution(struct ds_tizen_eom_output *output,
+ int *width, int *height)
+{
+ if (output == NULL)
+ return;
+
+ *width = output->physical_width;
+ *height = output->physical_height;
+}
+
+WL_EXPORT enum ds_tizen_eom_type
+ds_tizen_eom_get_output_type(struct ds_tizen_eom_output *output)
+{
+ if (output == NULL)
+ return DS_TIZEN_EOM_OUTPUT_TYPE_NONE;
+
+ return output->type;
+}
+
+WL_EXPORT void
+ds_tizen_eom_set_output_mode(struct ds_tizen_eom_output *output,
+ enum ds_tizen_eom_mode mode)
+{
+ if (output == NULL)
+ return;
+
+ output->mode = mode;
+}
+
+WL_EXPORT enum ds_tizen_eom_mode
+ds_tizen_eom_get_output_mode(struct ds_tizen_eom_output *output)
+{
+ if (output == NULL)
+ return DS_TIZEN_EOM_MODE_NONE;
+
+ return output->mode;
+}
+
+WL_EXPORT void
+ds_tizen_eom_set_output_status(struct ds_tizen_eom_output *output,
+ enum ds_tizen_eom_status status)
+{
+ if (output == NULL)
+ return;
+
+ output->status = status;
+}
+
+WL_EXPORT enum ds_tizen_eom_status
+ds_tizen_eom_get_output_status(struct ds_tizen_eom_output *output)
+{
+ if (output == NULL)
+ return DS_TIZEN_EOM_STATUS_NONE;
+
+ return output->status;
+}
+
+WL_EXPORT void
+ds_tizen_eom_set_output_attribute(struct ds_tizen_eom_output *output,
+ enum ds_tizen_eom_attribute attribute)
+{
+ if (output == NULL)
+ return;
+
+ output->attribute = attribute;
+}
+
+WL_EXPORT enum ds_tizen_eom_attribute
+ds_tizen_eom_get_output_attribute(struct ds_tizen_eom_output *output)
+{
+ if (output == NULL)
+ return DS_TIZEN_EOM_ATTRIBUTE_NONE;
+
+ return output->attribute;
+}
+
+WL_EXPORT void
+ds_tizen_eom_set_client_attribute(struct ds_tizen_eom_client *client,
+ enum ds_tizen_eom_attribute attribute)
+{
+ if (client == NULL)
+ return;
+
+ client->attribute = attribute;
+}
+
+WL_EXPORT enum ds_tizen_eom_attribute
+ds_tizen_eom_get_client_attribute(struct ds_tizen_eom_client *client)
+{
+ if (client == NULL)
+ return DS_TIZEN_EOM_ATTRIBUTE_NONE;
+
+ return client->attribute;
+}
+
+WL_EXPORT void
+ds_tizen_eom_set_client_attribute_state(struct ds_tizen_eom_client *client,
+ enum ds_tizen_eom_attribute_state attribute_state)
+{
+ if (client == NULL)
+ return;
+
+ client->attribute_state = attribute_state;
+}
+
+WL_EXPORT enum ds_tizen_eom_attribute_state
+ds_tizen_eom_get_client_attribute_state(struct ds_tizen_eom_client *client)
+{
+ if (client == NULL)
+ return DS_TIZEN_EOM_ATTRIBUTE_STATE_NONE;
+
+ return client->attribute_state;
+}
+
+WL_EXPORT void
+ds_tizen_eom_add_destroy_listener(struct ds_tizen_eom *eom,
+ struct wl_listener *listener)
+{
+ wl_signal_add(&eom->events.destroy, listener);
+}
+
+WL_EXPORT void
+ds_tizen_eom_add_set_attribute_listener(struct ds_tizen_eom *eom,
+ struct wl_listener *listener)
+{
+ wl_signal_add(&eom->events.set_attribute, listener);
+}
+
+WL_EXPORT void
+ds_tizen_eom_add_set_shell_window_listener(struct ds_tizen_eom *eom,
+ struct wl_listener *listener)
+{
+ wl_signal_add(&eom->events.set_shell_window, listener);
+}
+
+WL_EXPORT void
+ds_tizen_eom_add_client_destroy_listener(struct ds_tizen_eom *eom,
+ struct wl_listener *listener)
+{
+ wl_signal_add(&eom->events.client_destroy, listener);
+}
+
+WL_EXPORT void
+ds_tizen_eom_send_output_info(struct ds_tizen_eom *eom,
+ struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output,
+ enum ds_tizen_eom_error error)
+{
+ if (_ds_tizen_eom_check_valid_output(eom, output) == false) {
+ ds_err("invalid output parameter");
+ return;
+ }
+
+ if (_ds_tizen_eom_check_valid_client(eom, client) == false) {
+ ds_err("invalid client parameter");
+ return;
+ }
+
+ wl_eom_send_output_info(client->res, output->id,
+ _ds_tizen_eom_get_eom_type(output->type),
+ _ds_tizen_eom_get_eom_mode(output->mode),
+ output->width, output->height, output->physical_width, output->physical_height,
+ _ds_tizen_eom_get_eom_status(output->status), 1, 0, 0, 0);
+
+ ds_inf("send_output_info - id:%d, type:%d, mode:%d, conn:%d, w:%d, h:%d, w_mm:%d, h_mm:%d",
+ output->id, output->type, output->mode, output->status,
+ output->width, output->height, output->physical_width, output->physical_height);
+
+}
+
+WL_EXPORT void
+ds_tizen_eom_send_output_type(struct ds_tizen_eom *eom,
+ struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output)
+{
+ if (_ds_tizen_eom_check_valid_output(eom, output) == false) {
+ ds_err("invalid output parameter");
+ return;
+ }
+
+ if (_ds_tizen_eom_check_valid_client(eom, client) == false) {
+ ds_err("invalid client parameter");
+ return;
+ }
+
+ wl_eom_send_output_type(client->res, output->id,
+ _ds_tizen_eom_get_eom_type(output->type),
+ _ds_tizen_eom_get_eom_status(output->status));
+}
+
+WL_EXPORT void
+ds_tizen_eom_send_output_mode(struct ds_tizen_eom *eom,
+ struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output)
+{
+ if (_ds_tizen_eom_check_valid_output(eom, output) == false) {
+ ds_err("invalid output parameter");
+ return;
+ }
+
+ if (_ds_tizen_eom_check_valid_client(eom, client) == false) {
+ ds_err("invalid client parameter");
+ return;
+ }
+
+ wl_eom_send_output_mode(client->res, output->id,
+ _ds_tizen_eom_get_eom_mode(output->mode));
+}
+
+WL_EXPORT void
+ds_tizen_eom_send_output_attribute(struct ds_tizen_eom *eom,
+ struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output,
+ enum ds_tizen_eom_error error)
+{
+ if (_ds_tizen_eom_check_valid_output(eom, output) == false) {
+ ds_err("invalid output parameter");
+ return;
+ }
+
+ if (_ds_tizen_eom_check_valid_client(eom, client) == false) {
+ ds_err("invalid client parameter");
+ return;
+ }
+
+ wl_eom_send_output_attribute(client->res, output->id,
+ _ds_tizen_eom_get_eom_attribute(output->attribute),
+ _ds_tizen_eom_get_eom_attribute_state(client->attribute_state),
+ _ds_tizen_eom_get_tizen_eom_error(error));
+}
+
+WL_EXPORT void
+ds_tizen_eom_send_output_set_window(struct ds_tizen_eom *eom,
+ struct ds_tizen_eom_client *client, struct ds_tizen_eom_output *output,
+ enum ds_tizen_eom_error error)
+{
+ if (_ds_tizen_eom_check_valid_output(eom, output) == false) {
+ ds_err("invalid output parameter");
+ return;
+ }
+
+ if (_ds_tizen_eom_check_valid_client(eom, client) == false) {
+ ds_err("invalid client parameter");
+ return;
+ }
+
+ wl_eom_send_output_set_window(client->res, output->id,
+ _ds_tizen_eom_get_tizen_eom_error(error));
+}
+
+static void
+_ds_tizen_eom_handle_display_destroy(struct wl_listener *listener, void *data)
+{
+ struct ds_tizen_eom *eom;
+ struct ds_tizen_eom_output *output, *tmp;
+
+ eom = wl_container_of(listener, eom, destroy);
+
+ ds_inf("global destroy : eom(%p)", eom);
+
+ wl_signal_emit(&eom->events.destroy, eom);
+ wl_list_remove(&eom->destroy.link);
+ wl_global_destroy(eom->global);
+
+ wl_list_for_each_safe(output, tmp, &eom->outputs, link) {
+ wl_list_remove(&output->link);
+ free(output);
+ }
+ free(eom);
+}
+
+static struct ds_tizen_eom_output *
+_ds_tizen_eom_get_eom_output_by_id(struct ds_tizen_eom *eom, uint32_t id)
+{
+ struct ds_tizen_eom_output *output;
+
+ wl_list_for_each(output, &eom->outputs, link) {
+ if (output->id == id)
+ return output;
+ }
+
+ return NULL;
+}
+
+static void
+_ds_tizen_eom_handle_set_attribute(struct wl_client *client,
+ struct wl_resource *resource, uint32_t output_id, uint32_t attribute)
+{
+ struct ds_tizen_eom *eom;
+ struct ds_tizen_eom_output *output;
+ struct ds_tizen_eom_client *eom_client;
+ enum ds_tizen_eom_attribute eom_attribute;
+
+ eom_client = wl_resource_get_user_data(resource);
+ if (attribute > WL_EOM_ATTRIBUTE_EXCLUSIVE) {
+ ds_err("set attribute error : not supported attribute(%d)", attribute);
+ return;
+ }
+
+ eom = eom_client->eom;
+ output = _ds_tizen_eom_get_eom_output_by_id(eom, output_id);
+ if (output == NULL) {
+ ds_err("set attribute error : no eom output id(%d)", output_id);
+ return;
+ }
+
+ eom_attribute = _ds_tizen_eom_get_ds_eom_attribute(attribute);
+
+ struct ds_tizen_eom_event_set_attribute event = {
+ .output = output,
+ .client = eom_client,
+ .attribute = eom_attribute,
+ };
+
+ wl_signal_emit(&eom->events.set_attribute, &event);
+}
+
+static void
+_ds_tizen_eom_handle_set_shell_window(struct wl_client *client,
+ struct wl_resource *resource, uint32_t output_id, struct wl_resource *surface_resource)
+{
+ struct ds_tizen_eom *eom;
+ struct ds_tizen_eom_output *output;
+ struct ds_tizen_eom_client *eom_client;
+ struct ds_surface *surface;
+
+ eom_client = wl_resource_get_user_data(resource);
+
+ eom = eom_client->eom;
+ output = _ds_tizen_eom_get_eom_output_by_id(eom, output_id);
+ if (output == NULL) {
+ ds_err("set attribute error : no eom output id(%d)", output_id);
+ return;
+ }
+
+ surface = ds_surface_from_resource(surface_resource);
+
+ struct ds_tizen_eom_event_set_shell_window event = {
+ .output = output,
+ .client = eom_client,
+ .surface = surface,
+ };
+
+ wl_signal_emit(&eom->events.set_shell_window, &event);
+}
+
+static void
+_ds_tizen_eom_handle_get_output_info(struct wl_client *client,
+ struct wl_resource *resource, uint32_t output_id)
+{
+ struct ds_tizen_eom *eom;
+ struct ds_tizen_eom_output *output;
+ struct ds_tizen_eom_client *eom_client;
+
+ eom_client = wl_resource_get_user_data(resource);
+ eom = eom_client->eom;
+ output = _ds_tizen_eom_get_eom_output_by_id(eom, output_id);
+ if (output == NULL) {
+ ds_err("get output info error : no eom output id(%d)", output_id);
+ return;
+ }
+
+ wl_eom_send_output_info(eom_client->res, output->id,
+ _ds_tizen_eom_get_eom_type(output->type),
+ _ds_tizen_eom_get_eom_mode(output->mode),
+ output->width, output->height, output->physical_width, output->physical_height,
+ _ds_tizen_eom_get_eom_status(output->status), 1, 0, 0, 0);
+
+ ds_inf("get_output_info - id:%d, type:%d, mode:%d, conn:%d, w:%d, h:%d, w_mm:%d, h_mm:%d",
+ output->id, output->type, output->mode, output->status,
+ output->width, output->height, output->physical_width, output->physical_height);
+}
+#if 0
+static void
+_ds_tizen_eom_handle_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+ wl_resource_destroy(resource);
+}
+#endif
+static const struct wl_eom_interface eom_impl =
+{
+ _ds_tizen_eom_handle_set_attribute,
+ _ds_tizen_eom_handle_set_shell_window,
+ _ds_tizen_eom_handle_get_output_info,
+// _ds_tizen_eom_handle_destroy,
+};
+
+static void
+_ds_tizen_eom_client_cb_destroy(struct wl_resource *resource)
+{
+ struct ds_tizen_eom_client *eom_client;
+
+ ds_inf("_ds_tizen_eom_client_cb_destroy (res:%p)", resource);
+
+ eom_client = wl_resource_get_user_data(resource);
+
+ wl_signal_emit(&eom_client->eom->events.client_destroy, eom_client);
+ wl_list_remove(&eom_client->link);
+ free(eom_client);
+}
+
+static void
+_ds_tizen_eom_bind(struct wl_client *client, void *data, uint32_t version,
+ uint32_t id)
+{
+ struct ds_tizen_eom *eom = data;
+ struct ds_tizen_eom_client *eom_client;
+ struct ds_tizen_eom_output *output;
+
+ eom_client = calloc(1, sizeof *eom_client);
+ if (eom_client == NULL) {
+ wl_client_post_no_memory(client);
+ return;
+ }
+
+ eom_client->eom = eom;
+ eom_client->client = client;
+
+ eom_client->res = wl_resource_create(client, &wl_eom_interface,
+ MIN(version, TIZEN_EOM_VERSION), id);
+ if (eom_client->res == NULL) {
+ ds_err("eom bind error : wl_resource_create failed.");
+ wl_client_post_no_memory(client);
+ free(eom_client);
+ return;
+ }
+
+ wl_resource_set_implementation(eom_client->res, &eom_impl,
+ eom_client, _ds_tizen_eom_client_cb_destroy);
+
+ wl_eom_send_output_count(eom_client->res, eom->output_count);
+
+ wl_list_for_each(output, &eom->outputs, link) {
+ wl_eom_send_output_info(eom_client->res, output->id,
+ _ds_tizen_eom_get_eom_type(output->type),
+ _ds_tizen_eom_get_eom_mode(output->mode),
+ output->width, output->height, output->physical_width, output->physical_height,
+ _ds_tizen_eom_get_eom_status(output->status), 1, 0, 0, 0);
+ }
+
+ wl_list_insert(&eom->clients, &eom_client->link);
+}