diff options
author | SooChan Lim <sc1.lim@samsung.com> | 2015-06-05 16:22:36 +0900 |
---|---|---|
committer | SooChan Lim <sc1.lim@samsung.com> | 2015-06-05 16:23:11 +0900 |
commit | 55564857683db2936c2ced45f2e60314a0e41064 (patch) | |
tree | 3b5924a9e201670f6412738eac0e18a7c437baeb | |
parent | 4021d47b6818966447fa0912b20af0ec48480fa1 (diff) | |
download | libeom-55564857683db2936c2ced45f2e60314a0e41064.tar.gz libeom-55564857683db2936c2ced45f2e60314a0e41064.tar.bz2 libeom-55564857683db2936c2ced45f2e60314a0e41064.zip |
add initial version
Change-Id: I4cae25573ba0d886aada7109c384379485700eb7
-rw-r--r-- | AUTHORS | 0 | ||||
-rw-r--r-- | COPYING | 21 | ||||
-rw-r--r-- | ChangeLog | 0 | ||||
-rw-r--r-- | INSTALL | 0 | ||||
-rwxr-xr-x | Makefile.am | 28 | ||||
-rw-r--r-- | NEWS | 0 | ||||
-rwxr-xr-x | NOTICE | 3 | ||||
-rw-r--r-- | README | 0 | ||||
-rwxr-xr-x | autogen.sh | 12 | ||||
-rwxr-xr-x | configure.ac | 91 | ||||
-rw-r--r-- | doc/ui_eom_doc.h | 313 | ||||
-rwxr-xr-x | include/Makefile.am | 34 | ||||
-rwxr-xr-x | include/eom-connect.h | 75 | ||||
-rwxr-xr-x | include/eom.h | 503 | ||||
-rw-r--r-- | include/eom.pc.in | 12 | ||||
-rw-r--r-- | include/eom_internal.h | 52 | ||||
-rw-r--r-- | packaging/libeom.manifest | 5 | ||||
-rw-r--r-- | packaging/libeom.spec | 58 | ||||
-rwxr-xr-x | src/Makefile.am | 39 | ||||
-rwxr-xr-x | src/eom-connect.c | 82 | ||||
-rwxr-xr-x | src/eom-dbus.c | 548 | ||||
-rwxr-xr-x | src/eom-dbus.h | 66 | ||||
-rwxr-xr-x | src/eom-log.h | 83 | ||||
-rwxr-xr-x | src/eom-private.h | 65 | ||||
-rwxr-xr-x | src/eom.c | 1253 | ||||
-rw-r--r-- | tests/Makefile.am | 12 | ||||
-rwxr-xr-x | tests/eom-test-output.c | 88 |
27 files changed, 3443 insertions, 0 deletions
@@ -0,0 +1,21 @@ +Copyright 2013 Samsung Electronics co., Ltd. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/ChangeLog diff --git a/Makefile.am b/Makefile.am new file mode 100755 index 0000000..c7596e5 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,28 @@ +# Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved. +# +# Contact: +# SooChan Lim <sc1.lim@samsung.com> +# Boram Park <boram1288.park@samsung.com> +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sub license, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial portions +# of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +# IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +SUBDIRS = include src + @@ -0,0 +1,3 @@ +Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under MIT License. +Please, see the LICENSE.MIT file for MIT License terms and conditions. diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..904cd67 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,12 @@ +#! /bin/sh + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +ORIGDIR=`pwd` +cd $srcdir + +autoreconf -v --install || exit 1 +cd $ORIGDIR || exit $? + +$srcdir/configure --enable-maintainer-mode "$@" diff --git a/configure.ac b/configure.ac new file mode 100755 index 0000000..3f0a38c --- /dev/null +++ b/configure.ac @@ -0,0 +1,91 @@ +# Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved. +# +# Contact: +# SooChan Lim <sc1.lim@samsung.com> +# Boram Park <boram1288.park@samsung.com> +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sub license, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial portions +# of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +# IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +AC_PREREQ(2.60) +AC_INIT(libeom, 1.0.0) +AC_USE_SYSTEM_EXTENSIONS +AC_CONFIG_SRCDIR([Makefile.am]) +AM_INIT_AUTOMAKE([dist-bzip2]) + +AM_CONFIG_HEADER([config.h]) +AH_TOP([ +#ifndef __EOM_CONFIG_H__ +#define __EOM_CONFIG_H__ +]) +AH_BOTTOM([ +#endif /* __EOM_CONFIG_H__ */ +]) + +AC_DISABLE_STATIC +AC_PROG_LIBTOOL +AC_PROG_CC + +AC_HEADER_STDC +AC_SYS_LARGEFILE +AC_FUNC_ALLOCA + +# Enable quiet compiles on automake 1.11. +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + +# Checks for pkg-config packages +PKG_CHECK_MODULES(DBUS, dbus-1) +PKG_CHECK_MODULES(GLIB, glib-2.0 gobject-2.0) +PKG_CHECK_MODULES(ELEMENTARY, elementary) + +LIBEOM_CFLAGS="$DBUS_CFLAGS $GLIB_CFLAGS $ELEMENTARY_CFLAGS" +LIBEOM_LIBS="$DBUS_LIBS $GLIB_LIBS $ELEMENTARY_LIBS" + +PKG_CHECK_MODULES(CAPI, [capi-base-common >= 0.1.1], [CAPI_VER="yes"], [CAPI_VER="no"]) +if test "x$CAPI_VER" = "xyes"; then + AC_DEFINE(HAVE_CAPI_0_1_1,1,[The version of capi-base-common is over 0.1.1]) + LIBEOM_CFLAGS="$LIBEOM_CFLAGS $CAPI_CFLAGS" + LIBEOM_LIBS="$LIBEOM_LIBS $CAPI_LIBS" +fi + +AC_CHECK_LIB(dlog, __dlog_print, [have_dlog="yes"], [have_dlog="no"]) +if test "x$have_dlog" = "xyes"; then + PKG_CHECK_MODULES(DLOG, dlog) + AC_DEFINE([HAVE_DLOG], 1, "Have dlog support") + LIBEOM_CFLAGS="$LIBEOM_CFLAGS $DLOG_CFLAGS" + LIBEOM_LIBS="$LIBEOM_LIBS $DLOG_LIBS" +fi + +AC_SUBST([LIBEOM_CFLAGS]) +AC_SUBST([LIBEOM_LIBS]) + +# Checks for header files. +AC_HEADER_STDC + +AC_OUTPUT([Makefile + src/Makefile + include/Makefile + include/eom.pc + tests/Makefile]) + +echo "CFLAGS : $CFLAGS" +echo "LDFLAGS : $LDFLAGS" +echo "LIBEOM_CFLAGS: $LIBEOM_CFLAGS" +echo "LIBEOM_LIBS : $LIBEOM_LIBS" diff --git a/doc/ui_eom_doc.h b/doc/ui_eom_doc.h new file mode 100644 index 0000000..5fcd263 --- /dev/null +++ b/doc/ui_eom_doc.h @@ -0,0 +1,313 @@ +#ifndef __UI_EOM_DOC_H__
+#define __UI_EOM_DOC_H__
+
+/**************************************************************************
+
+External Output Manager (EOM)
+
+Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved.
+
+Contact:
+SooChan Lim <sc1.lim@samsung.com>
+Boram Park <boram1288.park@samsung.com>
+Changyeon Lee <cyeon.lee@samsung.com>
+JunKyeong Kim <jk0430.kim@samsung.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sub license, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/**
+ * @ingroup CAPI_UI_FRAMEWORK
+ * @defgroup CAPI_UI_EOM_MODULE External Output Manager
+ * @brief The External Output Manager provides APIs for external outputs.
+ *
+ * @section CAPI_UI_EOM_MODULE_HEADER Required Header
+ * #include <eom.h>
+ *
+ * @section CAPI_UI_EOM_MODULE_OVERVIEW Overview
+ * The External Output Manager (EOM) is for managing external outputs.
+ * User can get the information of external outputs and control them via
+ * eom API.
+ *
+ * @sample code
+#include <stdio.h>
+#include <gio/gio.h>
+#include <eom.h>
+#include <Elementary.h>
+#include <Ecore_X.h>
+
+typedef struct
+{
+ Evas_Object *external_window;
+
+ int hdmi_output_id;
+ int virtual_output_id;
+} SampleInfo;
+
+static void
+set_external_rect_bg_window (Evas_Object* win)
+{
+ Evas_Object *bg, *rect;
+
+ bg = elm_bg_add (win);
+ elm_win_resize_object_add (win, bg);
+ evas_object_size_hint_weight_set (bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_show (bg);
+
+ rect = evas_object_rectangle_add (evas_object_evas_get(win));
+ evas_object_color_set (rect, 0, 0, 0, 0);
+ evas_object_render_op_set (rect, EVAS_RENDER_COPY);
+
+ elm_win_resize_object_add (win, rect);
+ evas_object_size_hint_weight_set (rect, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_show (rect);
+ evas_object_show (win);
+}
+
+static void
+sample_notify_cb_output_add (eom_output_id output_id, void *user_data)
+{
+ SampleInfo *info = (SampleInfo*)user_data;
+
+ if (info->hdmi_output_id != output_id)
+ {
+ printf ("OUTPUT ADDED. SKIP. my output ID is %d\n", info->hdmi_output_id);
+ return;
+ }
+
+ printf ("output(%d) connected\n", output_id);
+
+ if (!info->external_window)
+ {
+ info->external_window = elm_win_add(NULL, "external_win", ELM_WIN_BASIC);
+ if (eom_set_output_window(info->hdmi_output_id, info->external_window) == EOM_ERROR_NONE)
+ {
+ set_external_rect_bg_window(info->external_window);
+ }
+ else
+ {
+ evas_object_del (info->external_window);
+ info->external_window = NULL;
+ }
+ }
+}
+
+static void
+sample_notify_cb_output_remove (eom_output_id output_id, void *user_data)
+{
+ SampleInfo *info = (SampleInfo*)user_data;
+
+ if (info->hdmi_output_id != output_id)
+ {
+ printf ("OUTPUT REMOVED. SKIP. my output ID is %d\n", info->hdmi_output_id);
+ return;
+ }
+
+ printf ("output(%d) disconnected\n", output_id);
+
+ if (info->external_window)
+ {
+ evas_object_del (info->external_window);
+ info->external_window = NULL;
+ }
+}
+
+static void
+sample_notify_cb_mode_changed (eom_output_id output_id, void *user_data)
+{
+ SampleInfo *info = (SampleInfo*)user_data;
+ eom_output_mode_e mode = EOM_OUTPUT_MODE_NONE;
+
+ if (info->hdmi_output_id != output_id)
+ {
+ printf ("MODE CHANGED. SKIP. my output ID is %d\n", info->hdmi_output_id);
+ return;
+ }
+
+ eom_get_output_mode(output_id, &mode);
+ printf ("output(%d) mode changed(%d)\n", output_id, mode);
+}
+
+static void
+sample_notify_cb_attribute_changed (eom_output_id output_id, void *user_data)
+{
+ SampleInfo *info = (SampleInfo*)user_data;
+ eom_output_attribute_e attribute = EOM_OUTPUT_ATTRIBUTE_NONE;
+ eom_output_attribute_state_e state = EOM_OUTPUT_ATTRIBUTE_STATE_NONE;
+
+ if (info->hdmi_output_id != output_id)
+ {
+ printf ("ATTR CHANGED. SKIP. my output ID is %d\n", info->hdmi_output_id);
+ return;
+ }
+
+ eom_get_output_attribute(output_id, &attribute);
+ eom_get_output_attribute_state(output_id, &state);
+
+ printf ("output(%d) attribute changed(%d, %d)\n", output_id, attribute, state);
+ if (state == EOM_OUTPUT_ATTRIBUTE_STATE_ACTIVE)
+ {
+ //active : display image to external window\n");
+ }
+ else if (state == EOM_OUTPUT_ATTRIBUTE_STATE_INACTIVE)
+ {
+ //inactive : stop displaying image to external window and destroy external window
+ if (info->external_window)
+ {
+ sample_destroy_window (info->external_window);
+ info->external_window = NULL;
+ }
+ }
+ else if (state == EOM_OUTPUT_ATTRIBUTE_STATE_LOST)
+ {
+ //lost : stop displaying image to external window, destroy external window and unset callbacks
+ if (info->external_window)
+ {
+ sample_destroy_window (info->external_window);
+ info->external_window = NULL;
+ }
+
+ eom_unset_output_added_cb(sample_notify_cb_output_add);
+ eom_unset_output_removed_cb(sample_notify_cb_output_remove);
+ eom_unset_mode_changed_cb(sample_notify_cb_mode_changed);
+ eom_unset_attribute_changed_cb(sample_notify_cb_attribute_changed);
+
+ eom_deinit ();
+ }
+}
+
+int
+sample_get_output_id (const char *output_name)
+{
+ eom_output_id *output_ids = NULL;
+ eom_output_id output_id = 0;
+ eom_output_type_e output_type = EOM_OUTPUT_TYPE_UNKNOWN;
+ int id_cnt = 0;
+ int i;
+
+ // get output_ids
+ output_ids = eom_get_eom_output_ids(&id_cnt);
+ if (id_cnt == 0)
+ {
+ printf ("no external outputs supported\n");
+ return 0;
+ }
+
+ // find output ids interested
+ for (i = 0; i < id_cnt; i++)
+ {
+ eom_get_output_type(output_ids[i], &output_type);
+ if (!strncmp(output_name, "HDMI", 4))
+ {
+ if (output_type == EOM_OUTPUT_TYPE_HDMIA || output_type == EOM_OUTPUT_TYPE_HDMIB)
+ {
+ output_id = output_ids[i];
+ break;
+ }
+ }
+ else if (!strncmp(output_name, "Virtual", 7))
+ {
+ if (output_type == EOM_OUTPUT_TYPE_VIRTUAL)
+ {
+ output_id = output_ids[i];
+ break;
+ }
+ }
+ }
+
+ if (output_ids)
+ free (output_ids);
+
+ return output_id;
+}
+
+int
+elm_main(int argc, char **argv)
+{
+ SampleInfo *info;
+ eom_error_e ret;
+ eom_output_mode_e output_mode = EOM_OUTPUT_MODE_NONE;
+ memset (info, 0x00, sizeof(SampleInfo));
+
+ if (eom_init () != EOM_ERROR_NONE)
+ return 0;
+
+ // get output id
+ info->hdmi_output_id = sample_get_output_id ("HDMI");
+ if (info->hdmi_output_id == 0)
+ {
+ printf ("error : HDMI output id is NULL.\n");
+ eom_deinit ();
+ return 0;
+ }
+ ret = eom_set_output_attribute(info->hdmi_output_id, EOM_OUTPUT_ATTRIBUTE_NORMAL);
+ if (ret != EOM_ERROR_NONE)
+ {
+ printf ("Set attribute fail. Cannot use external output\n");
+ eom_deinit ();
+ return 0;
+ }
+
+ if (ret == EOM_ERROR_NONE)
+ {
+ eom_get_output_mode(info->hdmi_output_id, &output_mode);
+ if (output_mode != EOM_OUTPUT_MODE_NONE)
+ {
+ //create external window(info->external_window)
+ info->external_window = elm_win_add(NULL, "external_win", ELM_WIN_BASIC);
+ if (eom_set_output_window(info->hdmi_output_id, info->external_window) == EOM_ERROR_NONE)
+ {
+ set_external_rect_bg_window(info->external_window);
+ }
+ else
+ {
+ evas_object_del (info->external_window);
+ info->external_window = NULL;
+ }
+ }
+
+ eom_set_output_added_cb(sample_notify_cb_output_add, info);
+ eom_set_output_removed_cb(sample_notify_cb_output_remove, info);
+ eom_set_mode_changed_cb(sample_notify_cb_mode_changed, info);
+ eom_set_attribute_changed_cb(sample_notify_cb_attribute_changed, info);
+ }
+
+ elm_run();
+
+ if (ret == EOM_ERROR_NONE)
+ {
+ eom_unset_output_added_cb(sample_notify_cb_output_add);
+ eom_unset_output_removed_cb(sample_notify_cb_output_remove);
+ eom_unset_mode_changed_cb(sample_notify_cb_mode_changed);
+ eom_unset_attribute_changed_cb(sample_notify_cb_attribute_changed);
+
+ eom_deinit ();
+ }
+
+ elm_shutdown();
+
+ return 0;
+}
+ * @endcode
+ */
+
+#endif /* __UI_EOM_DOC_H__ */
diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100755 index 0000000..d1a7d86 --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,34 @@ +# Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved. +# +# Contact: +# SooChan Lim <sc1.lim@samsung.com> +# Boram Park <boram1288.park@samsung.com> +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sub license, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial portions +# of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +# IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +libeomincludedir = $(includedir)/eom +libeominclude_HEADERS = \ + eom.h \ + eom_internal.h \ + eom-connect.h + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = eom.pc diff --git a/include/eom-connect.h b/include/eom-connect.h new file mode 100755 index 0000000..4cd8d8a --- /dev/null +++ b/include/eom-connect.h @@ -0,0 +1,75 @@ +/************************************************************************** + +eom (external output manager) + +Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: +SooChan Lim <sc1.lim@samsung.com> +Boram Park <boram1288.park@samsung.com> +Changyeon Lee <cyeon.lee@samsung.com> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef __EOM_CONNECT_H__ +#define __EOM_CONNECT_H__ + +/** + * @ingroup + * @addtogroup CAPI_UI_EOM_MODULE + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <eom.h> + +/** + * @file eom-connect.h + */ + +/** + * @brief Set mode to external output. + * @param[in] output : The pointer of external output instance + * @param[in] output_id : eom output id + * @return #EOM_ERROR_NONE if this function succeeds, otherwise error status value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #EOM_ERROR_SEND_MESSAGE_FAILE Message sending failure + * @retval #EOM_ERROR_OPERATE_MESSAGE_FAILE Message operation failure + * see #eom_output_mode_e + */ +int eom_output_set_mode (eom_output_id output_id, eom_output_mode_e mode); + + +#ifdef __cplusplus +} +#endif + +/** +* @} +*/ + +#endif /* __EOM_CONNECT_H__ */ diff --git a/include/eom.h b/include/eom.h new file mode 100755 index 0000000..55f3d17 --- /dev/null +++ b/include/eom.h @@ -0,0 +1,503 @@ +/************************************************************************** + +External Output Manager (EOM) + +Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: +SooChan Lim <sc1.lim@samsung.com> +Boram Park <boram1288.park@samsung.com> +Changyeon Lee <cyeon.lee@samsung.com> +JunKyeong Kim <jk0430.kim@samsung.com> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef __EOM_H__ +#define __EOM_H__ + +/** + * @addtogroup CAPI_UI_EOM_MODULE + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include <stddef.h> +#include <stdbool.h> +#include <string.h> +#include <tizen.h> +#include <Elementary.h> + +/** + * @file eom.h + */ +#ifndef TIZEN_ERROR_EOM +#define TIZEN_ERROR_EOM -0x02F20000 | 0x00 +#endif +/** + * @brief Enumeration of External Output Manager (EOM) error type + * @since_tizen 2.4 + */ +typedef enum +{ + EOM_ERROR_NONE = TIZEN_ERROR_NONE, /**< Success */ + EOM_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Memory allocation failure */ + EOM_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid input parameter */ + EOM_ERROR_NO_SUCH_DEVICE = TIZEN_ERROR_NO_SUCH_DEVICE, /**< Invalid external output instance */ + EOM_ERROR_CONNECTION_FAILURE = TIZEN_ERROR_EOM | 0x01, /**< Connection failure */ + EOM_ERROR_MESSAGE_SENDING_FAILURE = TIZEN_ERROR_EOM | 0x02, /**< Message sending failure */ + EOM_ERROR_MESSAGE_OPERATION_FAILURE = TIZEN_ERROR_EOM | 0x03, /**< Message operation failure */ +} eom_error_e; + +/** + * @brief Enumeration of external output type + * @since_tizen 2.4 + */ +typedef enum +{ + EOM_OUTPUT_TYPE_UNKNOWN, /**< Unknown output type */ + EOM_OUTPUT_TYPE_VGA, /**< VGA output */ + EOM_OUTPUT_TYPE_DVII, /**< DVII output type */ + EOM_OUTPUT_TYPE_DVID, /**< DVID output type */ + EOM_OUTPUT_TYPE_DVIA, /**< DVIA output type */ + EOM_OUTPUT_TYPE_COMPOSITE, /**< Composite output type */ + EOM_OUTPUT_TYPE_SVIDEO, /**< SVIDEO output type */ + EOM_OUTPUT_TYPE_LVDS, /**< LVDS output type */ + EOM_OUTPUT_TYPE_COMPONENT, /**< Component output type */ + EOM_OUTPUT_TYPE_9PINDIN, /**< 9PinDIN output type */ + EOM_OUTPUT_TYPE_DISPLAYPORT, /**< DisplayPort output type */ + EOM_OUTPUT_TYPE_HDMIA, /**< HDMIA output type */ + EOM_OUTPUT_TYPE_HDMIB, /**< HDMIB output type */ + EOM_OUTPUT_TYPE_TV, /**< TV output type */ + EOM_OUTPUT_TYPE_EDP, /**< EDP output type */ + EOM_OUTPUT_TYPE_VIRTUAL, /**< VIRTUAL output type */ + EOM_OUTPUT_TYPE_DSI, /**< DSI output type */ + EOM_OUTPUT_TYPE_MAX, +} eom_output_type_e; + +/** + * @brief Enumeration of external output mode + * @since_tizen 2.4 + */ +typedef enum +{ + EOM_OUTPUT_MODE_NONE, /**< None */ + EOM_OUTPUT_MODE_MIRROR, /**< Mirror mode */ + EOM_OUTPUT_MODE_PRESENTATION, /**< Presentation mode */ + EOM_OUTPUT_MODE_MAX, +} eom_output_mode_e; + +/** + * @brief Enumeration of External Output Manager (EOM) attributes + * @since_tizen 2.4 + */ +typedef enum +{ + EOM_OUTPUT_ATTRIBUTE_NONE, /**< None */ + EOM_OUTPUT_ATTRIBUTE_NORMAL, /**< Normal presentation mode window showing on external output */ + EOM_OUTPUT_ATTRIBUTE_EXCLUSIVE_SHARE, /**< Exclusive share presentation mode window showing on external output */ + EOM_OUTPUT_ATTRIBUTE_EXCLUSIVE, /**< Exclusive presentation mode window showing on external output */ + EOM_OUTPUT_ATTRIBUTE_MAX, +} eom_output_attribute_e; + +/** + * @brief Enumeration of External Output Manager (EOM) attribute state + * @since_tizen 2.4 + */ +typedef enum +{ + EOM_OUTPUT_ATTRIBUTE_STATE_NONE, /**< None */ + EOM_OUTPUT_ATTRIBUTE_STATE_ACTIVE, /**< Output attribute is active */ + EOM_OUTPUT_ATTRIBUTE_STATE_INACTIVE, /**< Output attribute is inactive */ + EOM_OUTPUT_ATTRIBUTE_STATE_LOST, /**< Cannot use external output */ + EOM_OUTPUT_ATTRIBUTE_STATE_MAX, +} eom_output_attribute_state_e; + +/** + * @brief Definition for external output ID + * @since_tizen 2.4 + */ +typedef unsigned int eom_output_id; + +/** + * @brief Called when External Output Manager (EOM) module sends output connection notification. + * @since_tizen 2.4 + * @param[in] output_id The output id which is connected output + * @param[in] user_data The pointer of user data which is passed to eom_output_added_cb function + * @see eom_set_output_added_cb() + * @see eom_unset_output_added_cb() + */ +typedef void (*eom_output_added_cb)(eom_output_id output_id, void *user_data); + +/** + * @brief Called when External Output Manager (EOM) module sends output disconnection notification. + * @since_tizen 2.4 + * @param[in] output_id The output id which is connected output + * @param[in] user_data The pointer of user data which is passed to eom_output_removed_cb function + * @see eom_set_output_removed_cb() + * @see eom_unset_output_removed_cb() + */ +typedef void (*eom_output_removed_cb)(eom_output_id output_id, void *user_data); + +/** + * @brief Called when External Output Manager (EOM) module sends output mode changing notification. + * @since_tizen 2.4 + * @param[in] output_id The output id which is connected output + * @param[in] user_data The pointer of user data which is passed to eom_mode_changed_cb function + * @see eom_set_mode_changed_cb() + * @see eom_unset_mode_changed_cb() + */ +typedef void (*eom_mode_changed_cb)(eom_output_id output_id, void *user_data); + +/** + * @brief Called when External Output Manager (EOM) module sends output attribute changing notification. + * @since_tizen 2.4 + * @param[in] output_id The output id which is connected output + * @param[in] user_data The pointer of user data which is passed to eom_attribute_changed_cb function + * @see eom_set_attribute_changed_cb() + * @see eom_unset_attribute_changed_cb() + */ +typedef void (*eom_attribute_changed_cb)(eom_output_id output_id, void *user_data); + +/** + * @brief Initializes External Output Manager (EOM). + * @details User should call this function previously for using EOM. + * @since_tizen 2.4 + * @remarks After all using, call eom_deinit() function for resource returning. + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_CONNECTION_FAILURE The EOM connection failure + * @see eom_deinit() + * @see #eom_error_e + */ +int eom_init (void); + +/** + * @brief Finalizes External Output Manager (EOM). + * @details User should call this function after using EOM to release all resources of EOM. + * @since_tizen 2.4 + * @see eom_init() + */ +void eom_deinit (void); + +/** + * @brief Registers a callback function to get output connection notification from External Output Manager (EOM) module. + * @since_tizen 2.4 + * @param[in] callback The function pointer of eom_output_added_cb callback function + * @param[in] user_data The pointer of user data which is passed to eom_output_added_cb function + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_OUT_OF_MEMORY Memory allocation failure + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @pre eom_init() + * @pre eom_get_eom_output_ids() + * @see eom_unset_output_added_cb() + * @see #eom_output_added_cb + */ +int eom_set_output_added_cb (eom_output_added_cb callback, void *user_data); + +/** + * @brief Unregisters the callback function. + * @since_tizen 2.4 + * @param[in] callback The function pointer of eom_output_added_cb callback function + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @pre eom_init() + * @pre eom_get_eom_output_ids() + * @see eom_set_output_added_cb() + * @see #eom_output_added_cb + */ +int eom_unset_output_added_cb (eom_output_added_cb callback); + +/** + * @brief Registers a callback function to get output disconnection notification from External Output Manager (EOM) module. + * @since_tizen 2.4 + * @param[in] callback The function pointer of eom_output_removed_cb callback function + * @param[in] user_data The pointer of user data which is passed to eom_output_removed_cb function + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_OUT_OF_MEMORY Memory allocation failure + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @pre eom_init() + * @pre eom_get_eom_output_ids() + * @see eom_unset_output_removed_cb() + * @see #eom_output_removed_cb + */ +int eom_set_output_removed_cb (eom_output_removed_cb callback, void *user_data); + +/** + * @brief Unregisters the callback function. + * @since_tizen 2.4 + * @param[in] callback The function pointer of eom_output_removed_cb callback function + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @pre eom_init() + * @pre eom_get_eom_output_ids() + * @see eom_set_output_removed_cb() + * @see #eom_output_removed_cb + */ +int eom_unset_output_removed_cb (eom_output_removed_cb callback); + +/** + * @brief Registers a callback function to get output mode changing notification from External Output Manager (EOM) module. + * @since_tizen 2.4 + * @param[in] callback The function pointer of eom_mode_changed_cb callback function + * @param[in] user_data The pointer of user data which is passed to eom_mode_changed_cb function + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_OUT_OF_MEMORY Memory allocation failure + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @pre eom_init() + * @pre eom_get_eom_output_ids() + * @see eom_unset_mode_changed_cb() + * @see #eom_mode_changed_cb + */ +int eom_set_mode_changed_cb (eom_mode_changed_cb callback, void *user_data); + +/** + * @brief Unregisters the callback function. + * @since_tizen 2.4 + * @param[in] callback The function pointer of eom_mode_changed_cb callback function + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @pre eom_init() + * @pre eom_get_eom_output_ids() + * @see eom_set_mode_changed_cb() + * @see #eom_mode_changed_cb + */ +int eom_unset_mode_changed_cb (eom_mode_changed_cb callback); + +/** + * @brief Registers a callback function to get output attribute changing notification from External Output Manager (EOM) module. + * @since_tizen 2.4 + * @param[in] callback The function pointer of eom_attribute_changed_cb callback function + * @param[in] user_data The pointer of user data which is passed to eom_attribute_changed_cb function + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_OUT_OF_MEMORY Memory allocation failure + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @pre eom_init() + * @pre eom_get_eom_output_ids() + * @see eom_unset_attribute_changed_cb() + * @see #eom_attribute_changed_cb + */ +int eom_set_attribute_changed_cb (eom_attribute_changed_cb callback, void *user_data); + +/** + * @brief Unregisters the callback function. + * @since_tizen 2.4 + * @param[in] callback The function pointer of eom_attribute_changed_cb callback function + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @pre eom_init() + * @pre eom_get_eom_output_ids() + * @see eom_set_attribute_changed_cb() + * @see #eom_attribute_changed_cb + */ +int eom_unset_attribute_changed_cb (eom_attribute_changed_cb callback); + +/** + * @brief Gets the IDs and count of external output. + * @details This function returns the IDs of external output which are available to connect + * to target device, and the count of them also. User can get the id of external output + * which user want to watch. + * @since_tizen 2.4 + * @remarks User should free return value by using free().\n + * The specific error code can be obtained using the get_last_result() method. + * Error codes are described in Exception section. + * @param[out] count The count of the eom_output_id supported by system + * @return The array of the eom_output_id if this function succeeds, otherwise NULL + * @retval The pointer of #eom_output_id + * @exception #EOM_ERROR_NONE Successful + * @exception #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @exception #EOM_ERROR_OUT_OF_MEMORY Memory allocation failure + * @pre eom_init() + * @see #eom_output_id + * @see #eom_error_e + */ +eom_output_id* eom_get_eom_output_ids (int *count); + +/** + * @brief Gets type of external output. + * @since_tizen 2.4 + * @remarks The specific error code can be obtained using the get_last_result() + * method. Error codes are described in Exception section. + * @param[in] output_id The id of external output device + * @param[out] type The type of external output instance + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @pre eom_init() + * @pre eom_get_eom_output_ids() + * @see #eom_output_id + * @see #eom_error_e + * @see #eom_output_type_e + */ +int eom_get_output_type (eom_output_id output_id, eom_output_type_e *type); + +/** + * @brief Gets mode of external output. + * @since_tizen 2.4 + * @remarks The specific error code can be obtained using the get_last_result() + * method. Error codes are described in Exception section. + * @param[in] output_id The id of external output device + * @param[out] mode The mode of external output instance + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #EOM_ERROR_NO_SUCH_DEVICE Invalid external output instance + * @pre eom_init() + * @pre eom_get_eom_output_ids() + * @see #eom_output_id + * @see #eom_error_e + * @see #eom_output_mode_e + */ +int eom_get_output_mode (eom_output_id output_id, eom_output_mode_e *mode); + +/** + * @brief Gets attribute of external output. + * @since_tizen 2.4 + * @remarks The specific error code can be obtained using the get_last_result() + * method. Error codes are described in Exception section. + * @param[in] output_id The id of external output device + * @param[out] attribute The attribute of external output instance + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #EOM_ERROR_NO_SUCH_DEVICE Invalid external output instance + * @pre eom_init() + * @pre eom_get_eom_output_ids() + * @see #eom_output_id + * @see #eom_error_e + * @see #eom_output_attribute_e + */ +int eom_get_output_attribute (eom_output_id output_id, eom_output_attribute_e *attribute); + +/** + * @brief Gets attribute state of external output. + * @since_tizen 2.4 + * @remarks The specific error code can be obtained using the get_last_result() + * method. Error codes are described in Exception section. + * @param[in] output_id The id of external output device + * @param[out] state The attribute state of external output instance + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #EOM_ERROR_NO_SUCH_DEVICE Invalid external output instance + * @pre eom_init() + * @pre eom_get_eom_output_ids() + * @see #eom_output_id + * @see #eom_error_e + * @see #eom_output_attribute_state_e + */ +int eom_get_output_attribute_state (eom_output_id output_id, eom_output_attribute_state_e *state); + +/** + * @brief Gets resolution of external output. + * @since_tizen 2.4 + * @param[in] output_id The id of external output device + * @param[out] width The width of external output instance + * @param[out] height The height of external output instance + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #EOM_ERROR_NO_SUCH_DEVICE Invalid external output instance + * @pre eom_init() + * @pre eom_get_eom_output_ids() + * @see #eom_output_id + * @see #eom_error_e + */ +int eom_get_output_resolution (eom_output_id output_id, int *width, int *height); + +/** + * @brief Gets physical width/height (millimeters) of external output. + * @since_tizen 2.4 + * @param[in] output_id The id of external output device + * @param[out] phy_width The physical mm width of external output instance + * @param[out] phy_height The physical mm height of external output instance + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #EOM_ERROR_NO_SUCH_DEVICE Invalid external output instance + * @pre eom_init() + * @pre eom_get_eom_output_ids() + * @see #eom_output_id + * @see #eom_error_e + */ +int eom_get_output_physical_size (eom_output_id output_id, int *phy_width, int *phy_height); + +/** + * @brief Sets the attribute of the external output ID. + * @details The application can set the External Output Manager (EOM) attribute to the external output ID. + * The EOM module manages the windows to display on external output and + * control the policy of external output. The application can recognize + * the attribute state and manage the resources when the application receives + * several notification callback from EOM module. + * @since_tizen 2.4 + * @param[in] output_id The id of external output device + * @param[in] attr The attribute of the external output + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #EOM_ERROR_MESSAGE_SENDING_FAILURE Communication failure with EOM module + * @retval #EOM_ERROR_MESSAGE_OPERATION_FAILURE Operation failure + * @pre eom_init() + * @pre eom_get_eom_output_ids() + * @see #eom_output_id + * @see #eom_error_e + */ +int eom_set_output_attribute (eom_output_id output_id, eom_output_attribute_e attr); + +/** + * @brief Sets window to the external output best resolution of external output device. + * @since_tizen 2.4 + * @param[in] output_id The id of external output device + * @param[in] win The pointer of evas object + * @return 0 on success, otherwise a negative error value + * @retval #EOM_ERROR_NONE Successful + * @retval #EOM_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #EOM_ERROR_MESSAGE_SENDING_FAILURE Communication failure with EOM module + * @retval #EOM_ERROR_MESSAGE_OPERATION_FAILURE Operation failure + * @pre eom_init() + * @pre eom_get_eom_output_ids() + * @see #eom_output_id + * @see #eom_error_e + */ +int eom_set_output_window (eom_output_id output_id, Evas_Object *win); + +#ifdef __cplusplus +} +#endif + +/** +* @} +*/ + +#endif /* __EOM_H__ */ diff --git a/include/eom.pc.in b/include/eom.pc.in new file mode 100644 index 0000000..b795246 --- /dev/null +++ b/include/eom.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: eom +Description: The External Output Manager debug Library +Version: @PACKAGE_VERSION@ +Requires.private: dbus-1 gio-unix-2.0 +Requires: capi-base-common +Cflags: -I${includedir}/eom +Libs: -L${libdir} -leom diff --git a/include/eom_internal.h b/include/eom_internal.h new file mode 100644 index 0000000..dd750d0 --- /dev/null +++ b/include/eom_internal.h @@ -0,0 +1,52 @@ +/************************************************************************** + +eom (external output manager) + +Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: +SooChan Lim <sc1.lim@samsung.com> +Boram Park <boram1288.park@samsung.com> +Changyeon Lee <cyeon.lee@samsung.com> +JunKyeong Kim <jk0430.kim@samsung.com> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef __EOM_INTERNAL_H__ +#define __EOM_INTERNAL_H__ + +/** + * @brief Enumeration of eom notify type + * @since_tizen 2.4 + */ +typedef enum +{ + EOM_OUTPUT_NOTIFY_NONE, /**< None notify */ + EOM_OUTPUT_NOTIFY_ADD, /**< Output add notify */ + EOM_OUTPUT_NOTIFY_REMOVE, /**< Output remove notify */ + EOM_OUTPUT_NOTIFY_MODE_CHANGED, /**< Mode change notify */ + EOM_OUTPUT_NOTIFY_ATTRIBUTE_CHANGED, /**< Attribute change notify */ + EOM_OUTPUT_NOTIFY_MAX, +} eom_output_notify_type_e; + +#endif /* __EOM_INTERNAL_H__ */ diff --git a/packaging/libeom.manifest b/packaging/libeom.manifest new file mode 100644 index 0000000..017d22d --- /dev/null +++ b/packaging/libeom.manifest @@ -0,0 +1,5 @@ +<manifest> + <request> + <domain name="_"/> + </request> +</manifest> diff --git a/packaging/libeom.spec b/packaging/libeom.spec new file mode 100644 index 0000000..3128578 --- /dev/null +++ b/packaging/libeom.spec @@ -0,0 +1,58 @@ +Name: libeom +Summary: External Output Manager Library +Version: 1.0.0 +Release: 1 +Group: Graphics/X Window System +License: MIT +Source0: %{name}-%{version}.tar.gz +Source1001: libeom.manifest + +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(dbus-1) +BuildRequires: pkgconfig(gio-unix-2.0) +BuildRequires: pkgconfig(capi-base-common) +BuildRequires: pkgconfig(elementary) + +%description +This package provides the runtime library to manage eo(External Output) + +%package devel +Summary: External Output Manager Library development package +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} +Requires: pkgconfig(capi-base-common) + +%description devel +External Output Manager Library development package + +%prep +%setup -q +cp %{SOURCE1001} . + +%build +export CFLAGS="-g -O0 -Wall -Werror -Wno-error=deprecated-declarations" +export LDFLAGS="$LDFLAGS -Wl,--hash-style=both -Wl,--as-needed" +%reconfigure --disable-dlog --disable-static +make %{?_smp_mflags} + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/usr/share/license +cp -af COPYING %{buildroot}/usr/share/license/%{name} +%make_install + +%remove_docs + +%files +%manifest %{name}.manifest +%defattr(-,root,root,-) +/usr/share/license/%{name} +%{_libdir}/libeom.so.* + +%files devel +%manifest %{name}.manifest +%dir %{_includedir}/eom/ +%{_includedir}/eom/*.h +%{_libdir}/libeom.so +%{_libdir}/pkgconfig/eom.pc + diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100755 index 0000000..56e49ad --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,39 @@ +# Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved. +# +# Contact: +# SooChan Lim <sc1.lim@samsung.com> +# Boram Park <boram1288.park@samsung.com> +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sub license, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial portions +# of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +# IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +libeom_la_LTLIBRARIES = libeom.la +libeom_ladir = $(libdir) +libeom_la_LIBADD = @LIBEOM_LIBS@ +libeom_la_LDFLAGS = ${LDFLAGS} +libeom_la_CFLAGS = \ + ${CFLAGS} \ + @LIBEOM_CFLAGS@ \ + -I$(top_srcdir)/include + +libeom_la_SOURCES = \ + eom.c \ + eom-connect.c \ + eom-dbus.c diff --git a/src/eom-connect.c b/src/eom-connect.c new file mode 100755 index 0000000..1b95167 --- /dev/null +++ b/src/eom-connect.c @@ -0,0 +1,82 @@ +/************************************************************************** + +eom (external output manager) + +Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: +SooChan Lim <sc1.lim@samsung.com> +Boram Park <boram1288.park@samsung.com> +Changyeon Lee <cyeon.lee@samsung.com> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include <config.h> + +#include "eom.h" +#include "eom-log.h" +#include "eom-dbus.h" +#include "eom-connect.h" +#include "eom-private.h" + +API int +eom_output_set_mode (eom_output_id output_id, eom_output_mode_e mode) +{ + bool ret = false; + GValueArray *msg_array; + GValueArray *ret_array; + GValue v = G_VALUE_INIT; + + RETV_IF_FAIL (mode < EOM_OUTPUT_MODE_MAX, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + INFO ("mode: %d\n", mode); + + msg_array = g_value_array_new (0); + + g_value_init (&v, G_TYPE_INT); + g_value_set_int (&v, output_id); + msg_array = g_value_array_append (msg_array, &v); + g_value_set_int (&v, mode); + msg_array = g_value_array_append (msg_array, &v); + + ret_array = eom_dbus_client_send_message ("SetMode", msg_array); + g_value_array_free (msg_array); + if (!ret_array) + { + _eom_mutex_unlock (); + return EOM_ERROR_MESSAGE_SENDING_FAILURE; + } + + ret = g_value_get_int (g_value_array_get_nth (ret_array, 0)); + + g_value_array_free (ret_array); + + INFO ("SetMode: %s", (ret)?"success":"failed"); + + _eom_mutex_unlock (); + + return (ret)?EOM_ERROR_NONE:EOM_ERROR_MESSAGE_OPERATION_FAILURE; +} + diff --git a/src/eom-dbus.c b/src/eom-dbus.c new file mode 100755 index 0000000..bf5bf6a --- /dev/null +++ b/src/eom-dbus.c @@ -0,0 +1,548 @@ +/************************************************************************** + +eom (external output manager) + +Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: +SooChan Lim <sc1.lim@samsung.com> +Boram Park <boram1288.park@samsung.com> +Changyeon Lee <cyeon.lee@samsung.com> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include <config.h> +#include <dbus/dbus.h> +#include <string.h> +#include "eom.h" +#include "eom-log.h" +#include "eom-dbus.h" + +#define REPLY_TIME 1000 +#define ARGV_NUM 64 + +typedef struct _EomDBusClientInfo +{ + DBusConnection *conn; + char name[STR_LEN]; + char rule[STR_LEN]; + GSource* src; + EomDBusClientMethod *methods; + int fd; +} EomDBusClientInfo; + +static EomDBusClientInfo client_info; + +static void _eom_dbus_client_deinit (EomDBusClientInfo *info); + +static int +_eom_dbus_need_private_conn (void) +{ + char *env = getenv("EOM_PRIVATE_CONN"); + + if(env) + { + return (atoi(env) > 0) ? 1 : 0; + INFO ("EOM_PRIVATE_CONN = %s", env); + } + + return 0; +} + +static int +_eom_dbus_convert_gvalue_to_message (GValueArray *array, DBusMessage *msg) +{ + DBusMessageIter iter; + int i; + + if (!array) + return 1; + + if (array->n_values <= 0) + return 1; + + dbus_message_iter_init_append (msg, &iter); + + INFO ("[EOM_CLIENT:%s] n_values(%d)", client_info.name, array->n_values); + + for (i = 0; i < array->n_values; i++) + { + GValue *v = g_value_array_get_nth (array, i); + GType type = v->g_type; + + INFO ("[EOM_CLIENT:%s] type(%d)", client_info.name, type); + + switch (type) + { + case G_TYPE_INT: + { + int integer = g_value_get_int (v); + + if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &integer)) + { + ERR ("[EOM_CLIENT:%s] failed: int append", client_info.name); + return 0; + } + } + break; + case G_TYPE_UINT: + { + unsigned int uinteger = g_value_get_uint (v); + + if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &uinteger)) + { + ERR ("[EOM_CLIENT:%s] failed: uint append", client_info.name); + return 0; + } + } + break; + case G_TYPE_STRING: + { + char *string = (char*)g_value_get_string (v); + + if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, (void*)&string)) + { + ERR ("[EOM_CLIENT:%s] failed: uint append", client_info.name); + return 0; + } + } + break; + case G_TYPE_VARIANT: + { + GVariant *variant = g_value_get_variant (v); + int data_size = g_variant_get_size (variant); + void *data = (void*)g_variant_get_data (variant); + DBusMessageIter sub; + + RETV_IF_FAIL (data != NULL, 0); + RETV_IF_FAIL (data_size > 0, 0); + + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "y", &sub); + if (!dbus_message_iter_append_fixed_array (&sub, DBUS_TYPE_BYTE, (void*)&data, data_size)) + { + ERR ("[EOM_CLIENT:%s] failed: uint append", client_info.name); + return 0; + } + dbus_message_iter_close_container(&iter, &sub); + } + break; + default: + return 0; + } + } + + return 1; +} + +static GValueArray* +_eom_dbus_convert_message_to_gvalue (DBusMessage *msg) +{ + GValueArray *array; + DBusMessageIter iter; + + if (!dbus_message_iter_init (msg, &iter)) + return NULL; + + array = g_value_array_new (0); + + do + { + int type = dbus_message_iter_get_arg_type (&iter); + GValue v = G_VALUE_INIT; + + INFO ("[EOM_CLIENT:%s] type(%c(%d))", client_info.name, (char)type, type); + + switch (type) + { + case DBUS_TYPE_INT32: + { + int integer = 0; + dbus_message_iter_get_basic (&iter, &integer); + g_value_init (&v, G_TYPE_INT); + g_value_set_int (&v, integer); + array = g_value_array_append (array, &v); + g_value_unset (&v); + } + break; + case DBUS_TYPE_UINT32: + { + unsigned int uinteger = 0; + dbus_message_iter_get_basic (&iter, &uinteger); + g_value_init (&v, G_TYPE_UINT); + g_value_set_uint (&v, uinteger); + array = g_value_array_append (array, &v); + g_value_unset (&v); + } + break; + case DBUS_TYPE_STRING: + { + char *string = NULL; + dbus_message_iter_get_basic (&iter, &string); + g_value_init (&v, G_TYPE_STRING); + g_value_set_string (&v, string); + array = g_value_array_append (array, &v); + g_value_unset (&v); + } + break; + default: + NEVER_GET_HERE (); + g_value_array_free (array); + return NULL; + } + } + while (dbus_message_iter_has_next (&iter) && dbus_message_iter_next (&iter)); + + return array; +} + +static void +_eom_dbus_client_process_message (EomDBusClientInfo *info, DBusMessage *msg) +{ + EomDBusClientMethod **prev; + DBusError err; + + dbus_error_init (&err); + + INFO ("[CLIENT] Process a message (%s.%s)", + dbus_message_get_interface (msg), dbus_message_get_member (msg)); + + RET_IF_FAIL (info->conn != NULL); + + for (prev = &info->methods; *prev; prev = &(*prev)->next) + { + EomDBusClientMethod *method = *prev; + + if (!strcmp (dbus_message_get_member (msg), method->name)) + { + GValueArray *array = _eom_dbus_convert_message_to_gvalue (msg); + + if (method->func) + method->func (method->data, array); + + if (array) + g_value_array_free (array); + + dbus_error_free (&err); + + return; + } + } +} + + +gboolean +_eom_dbus_client_cb (GIOChannel *src, GIOCondition cond, gpointer data) +{ + EomDBusClientInfo *info = (EomDBusClientInfo*)data; + + if (!info || !info->conn || info->fd < 0) + return false; + + do + { + dbus_connection_read_write_dispatch (info->conn, 0); + } + while (info->conn && + dbus_connection_get_is_connected (info->conn) && + dbus_connection_get_dispatch_status (info->conn) == + DBUS_DISPATCH_DATA_REMAINS); + + return true; +} + + +static DBusHandlerResult +_eom_dbus_client_msg_handler (DBusConnection *connection, DBusMessage *msg, void *data) +{ + EomDBusClientInfo *info = (EomDBusClientInfo*)data; + + if (!info || !info->conn || !msg) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + INFO("[Client] Got a message (%s.%s)", + dbus_message_get_interface (msg), dbus_message_get_member (msg)); + + _eom_dbus_client_process_message (info, msg); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +_eom_dbus_client_msg_filter (DBusConnection *conn, DBusMessage *msg, void *data) +{ + EomDBusClientInfo *info = (EomDBusClientInfo*)data; + + if (!info) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (dbus_message_is_signal (msg, DBUS_INTERFACE_LOCAL, "Disconnected")) + { + INFO ("[EOM] disconnected by signal"); + _eom_dbus_client_deinit (info); + + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static int +_eom_dbus_client_init(EomDBusClientInfo *info) +{ + DBusError err; + int ret; + DBusObjectPathVTable vtable = {.message_function = _eom_dbus_client_msg_handler, }; + GIOChannel* channel; + + dbus_error_init (&err); + + if (_eom_dbus_need_private_conn ()) + info->conn = dbus_bus_get_private (DBUS_BUS_SYSTEM, &err); + else + info->conn = dbus_bus_get (DBUS_BUS_SYSTEM, &err); + + if (dbus_error_is_set (&err)) + { + ERR ("[EOM] failed: connection (%s)", err.message); + goto free_err; + } + if (!info->conn) + { + ERR ("[EOM] failed: connection NULL"); + goto free_err; + } + + ret = dbus_bus_request_name (info->conn, info->name, + DBUS_NAME_FLAG_REPLACE_EXISTING , &err); + if (dbus_error_is_set (&err)) + { + ERR ("[EOM] failed: request name (%s)", err.message); + goto free_conn; + } + if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) + { + ERR ("[EOM] failed: Not Primary Owner (%d)", ret); + goto free_conn; + } + + snprintf (info->rule, sizeof (info->rule), "interface='%s'", + EOM_DBUS_INTERFACE); + + dbus_bus_add_match (info->conn, info->rule, &err); + dbus_connection_flush(info->conn); + if (dbus_error_is_set (&err)) + { + ERR ("[EOM] failed: add match (%s)", err.message); + goto free_name; + } + + if (!dbus_connection_register_object_path (info->conn, + EOM_DBUS_PATH, &vtable, + info)) + { + ERR ("[EOM] failed: register object path"); + goto free_match; + } + + dbus_connection_set_exit_on_disconnect (info->conn, FALSE); + + if (!dbus_connection_add_filter (info->conn, _eom_dbus_client_msg_filter, info, NULL)) + { + ERR ("[EOM] failed: add filter (%s)", err.message); + goto free_register; + } + + if (!dbus_connection_get_unix_fd (info->conn, &info->fd) || info->fd < 0) + { + ERR ("[EOM] failed: get fd"); + goto free_filter; + } + + dbus_error_free (&err); + + channel = g_io_channel_unix_new(info->fd); + g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL); + + info->src = g_io_create_watch(channel, G_IO_IN); + g_source_set_callback(info->src, (GSourceFunc)_eom_dbus_client_cb, (gpointer)info, NULL); + g_source_attach(info->src, NULL); + + g_io_channel_unref(channel); + + INFO("[EOM_CLIENT] connected"); + + return 1; + +free_filter: + dbus_connection_remove_filter (info->conn, _eom_dbus_client_msg_filter, info); +free_register: + dbus_connection_unregister_object_path (info->conn, EOM_DBUS_PATH); +free_match: + dbus_bus_remove_match (info->conn, info->rule, &err); + dbus_error_free (&err); +free_name: + dbus_bus_release_name (info->conn, info->name, &err); + dbus_error_free (&err); +free_conn: + dbus_connection_close (info->conn); +free_err: + dbus_error_free (&err); + info->conn = NULL; + info->fd = -1; + + return 0; +} + +static void +_eom_dbus_client_deinit (EomDBusClientInfo *info) +{ + DBusError err; + + if (!info->conn) + return; + + if (info->src) + { + g_source_destroy (info->src); + g_source_unref (info->src); + } + + if (info->conn) + { + dbus_error_init (&err); + dbus_bus_remove_match (info->conn, info->rule, &err); + dbus_error_free (&err); + dbus_bus_release_name (info->conn, info->name, &err); + dbus_error_free (&err); + dbus_connection_unref (info->conn); + } + + memset (info, 0, sizeof (EomDBusClientInfo)); + info->fd = -1; + + INFO ("[EOM] disconnected"); +} + +bool +eom_dbus_client_connect (void) +{ + if (client_info.conn) + return true; + + snprintf (client_info.name, STR_LEN, "org.eom.client%d", getpid()); + + client_info.fd = -1; + + if(!_eom_dbus_client_init (&client_info)) + return false; + + return true; +} + +void +eom_dbus_client_disconnect (void) +{ + _eom_dbus_client_deinit (&client_info); +} + +bool +eom_dbus_client_add_method (EomDBusClientMethod *method) +{ + EomDBusClientMethod **prev; + + for (prev = &client_info.methods; *prev; prev = &(*prev)->next); + + method->next = NULL; + *prev = method; + + return true; +} + +void +eom_dbus_client_remove_method (EomDBusClientMethod *method) +{ + EomDBusClientMethod **prev; + + for (prev = &client_info.methods; *prev; prev = &(*prev)->next) + if (*prev == method) + { + *prev = method->next; + method->next = NULL; + break; + } +} + +GValueArray* +eom_dbus_client_send_message (char* method, GValueArray *array) +{ + DBusMessage *msg = NULL; + DBusMessage *reply_msg = NULL; + GValueArray *ret_array = NULL; + DBusError err; + + RETV_IF_FAIL (client_info.conn != NULL, NULL); + + dbus_error_init (&err); + + msg = dbus_message_new_method_call (EOM_DBUS_SERVER, EOM_DBUS_PATH, + EOM_DBUS_INTERFACE, method); + GOTO_IF_FAIL (msg != NULL, err_send); + + INFO ("[EOM_CLIENT:%s] Send message(%s)", client_info.name, method); + + if (!_eom_dbus_convert_gvalue_to_message (array, msg)) + { + ERR ("[EOM_CLIENT:%s] failed: gvalue_to_message", client_info.name); + goto err_send; + } + + reply_msg = dbus_connection_send_with_reply_and_block (client_info.conn, msg, + REPLY_TIME, &err); + if (dbus_error_is_set (&err)) + { + ERR ("[EOM_CLIENT:%s] failed: send (%s)", client_info.name, err.message); + goto err_send; + } + GOTO_IF_FAIL (reply_msg != NULL, err_send); + + INFO ("[EOM_CLIENT:%s] Got reply", client_info.name); + + ret_array = _eom_dbus_convert_message_to_gvalue (reply_msg); + + dbus_message_unref(msg); + dbus_message_unref(reply_msg); + dbus_error_free (&err); + + return ret_array; +err_send: + if (msg) + dbus_message_unref(msg); + if (reply_msg) + dbus_message_unref(reply_msg); + if (ret_array) + g_value_array_free (ret_array); + + dbus_error_free (&err); + + return NULL; +} diff --git a/src/eom-dbus.h b/src/eom-dbus.h new file mode 100755 index 0000000..e8862e2 --- /dev/null +++ b/src/eom-dbus.h @@ -0,0 +1,66 @@ +/************************************************************************** + +eom (external output manager) + +Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: +SooChan Lim <sc1.lim@samsung.com> +Boram Park <boram1288.park@samsung.com> +Changyeon Lee <cyeon.lee@samsung.com> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef __EOM_DBUS_H__ +#define __EOM_DBUS_H__ + +#include <stdbool.h> +#include <glib.h> +#include <glib-object.h> +#include "eom.h" + +#define EOM_DBUS_SERVER "org.eom.server" +#define EOM_DBUS_CLIENT "org.eom.client" +#define EOM_DBUS_INTERFACE "org.eom.interface" +#define EOM_DBUS_PATH "/org/eom/path" + +#define STR_LEN 128 + +typedef void (*MethodFunc) (void *data, GValueArray *noti_array); + +typedef struct _EomDBusClientMethod +{ + char name[STR_LEN]; + MethodFunc func; + void *data; + + struct _EomDBusClientMethod *next; +} EomDBusClientMethod; + +bool eom_dbus_client_connect (void); +void eom_dbus_client_disconnect (void); +GValueArray* eom_dbus_client_send_message (char* method, GValueArray *array); +bool eom_dbus_client_add_method (EomDBusClientMethod *method); +void eom_dbus_client_remove_method (EomDBusClientMethod *method); + +#endif /* __EOM_DBUS_H__ */ diff --git a/src/eom-log.h b/src/eom-log.h new file mode 100755 index 0000000..4a86eb0 --- /dev/null +++ b/src/eom-log.h @@ -0,0 +1,83 @@ +/************************************************************************** + +eom (external output manager) + +Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: +SooChan Lim <sc1.lim@samsung.com> +Boram Park <boram1288.park@samsung.com> +Changyeon Lee <cyeon.lee@samsung.com> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef __EOM_LOG_H__ +#define __EOM_LOG_H__ + +#include <config.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> + +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + +#undef HAVE_DLOG + +extern bool eom_debug_on; + +#ifndef HAVE_CAPI_0_1_1 +static inline void set_last_result (int i) {;} +#endif + +#ifdef HAVE_DLOG +#define LOG_TAG "EOM" +#include <dlog.h> +#define INFO(fmt, arg...) \ + if (eom_debug_on) SECURE_SLOGI(fmt, ##arg) +#define WARN(fmt, arg...) \ + if (eom_debug_on) SECURE_SLOGW(fmt, ##arg) +#define ERR(fmt, arg...) SECURE_SLOGE(fmt, ##arg) +#define ERRNO(fmt, arg...) SECURE_SLOGE("(err=%s(%d)) "fmt, strerror(errno), errno, ##arg) +#define FATAL(fmt, arg...) SECURE_SLOGF(fmt, ##arg) +#else /* HAVE_DLOG */ +#include <stdlib.h> +#define INFO(fmt, arg...) \ + if (eom_debug_on) fprintf(stdout,"[%s:%d] "fmt"\n", __FUNCTION__, __LINE__, ##arg) +#define WARN(fmt, arg...) \ + if (eom_debug_on) fprintf(stderr,"[%s:%d] "fmt"\n", __FUNCTION__, __LINE__, ##arg) +#define ERR(fmt, arg...) fprintf(stderr,"[%s:%d] "fmt"\n", __FUNCTION__, __LINE__, ##arg) +#define ERRNO(fmt, arg...) fprintf(stderr,"[%s:%d](err=%s(%d)) "fmt"\n", __FUNCTION__, __LINE__, strerror(errno), errno, ##arg) +#define FATAL(fmt, arg...) fprintf(stderr,"[%s:%d] "fmt"\n", __FUNCTION__, __LINE__, ##arg) +#endif /* HAVE_DLOG */ + +#define WARN_IF_FAIL(cond) {if (!(cond)) { ERR ("'%s' failed", #cond);}} +#define RET_IF_FAIL(cond) {if (!(cond)) { ERR ("'%s' failed", #cond); return; }} +#define RETV_IF_FAIL(cond, val) {if (!(cond)) { ERR ("'%s' failed", #cond); return val; }} +#define RETV_IF_ERRNO(cond, val, errno) {if (!(cond)) { ERRNO ("'%s' failed", #cond); return val; }} +#define GOTO_IF_FAIL(cond, dst) {if (!(cond)) { ERR ("'%s' failed", #cond); goto dst; }} +#define GOTO_IF_ERRNO(cond, dst, errno) {if (!(cond)) { ERRNO ("'%s' failed", #cond); goto dst; }} +#define NEVER_GET_HERE() ERR("** NEVER GET HERE **\n") + +#endif /* __EOM_LOG_H__ */ diff --git a/src/eom-private.h b/src/eom-private.h new file mode 100755 index 0000000..78d98d0 --- /dev/null +++ b/src/eom-private.h @@ -0,0 +1,65 @@ +/************************************************************************** + +eom (external output manager) + +Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: +SooChan Lim <sc1.lim@samsung.com> +Boram Park <boram1288.park@samsung.com> +Changyeon Lee <cyeon.lee@samsung.com> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef __EOM_PRIVATE_H__ +#define __EOM_PRIVATE_H__ + +#include "eom.h" + +typedef struct +{ + eom_output_id id; + eom_output_type_e type; + + eom_output_mode_e output_mode; + eom_output_attribute_e attribute; + eom_output_attribute_state_e state; + + int width; + int height; + int mm_width; + int mm_height; +} eom_output_info; + +struct _eom_output +{ + eom_output_id id; + eom_output_type_e type; + + eom_output_info *output_info; +}; + +void _eom_mutex_lock (void); +void _eom_mutex_unlock (void); + +#endif /* __EOM_PRIVATE_H__ */ diff --git a/src/eom.c b/src/eom.c new file mode 100755 index 0000000..d60bf50 --- /dev/null +++ b/src/eom.c @@ -0,0 +1,1253 @@ +/************************************************************************** + +eom (external output manager) + +Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved. + +Contact: +SooChan Lim <sc1.lim@samsung.com> +Boram Park <boram1288.park@samsung.com> +Changyeon Lee <cyeon.lee@samsung.com> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include <config.h> + +#include <glib.h> +#include <string.h> +#include <errno.h> +#include <pthread.h> + +#include "eom.h" +#include "eom_internal.h" +#include "eom-log.h" +#include "eom-dbus.h" +#include "eom-private.h" + +typedef struct +{ + eom_output_notify_type_e type; /**< External output type */ + eom_output_id output_id; /**< External output id */ +} eom_output_notify_base_s; + +typedef struct +{ + eom_output_notify_type_e type; /**< External output type */ + eom_output_id output_id; /**< External output id */ +} eom_output_notify_add_s; + +typedef struct +{ + eom_output_notify_type_e type; /**< External output type */ + eom_output_id output_id; /**< External output id */ +} eom_output_notify_remove_s; + +typedef struct +{ + eom_output_notify_type_e type; /**< External output type */ + eom_output_id output_id; /**< External output id */ + eom_output_mode_e old_mode; /**< External output mode */ + eom_output_mode_e new_mode; /**< External output mode */ +} eom_output_notify_mode_change_s; + +typedef struct +{ + eom_output_notify_type_e type; /**< External output type */ + eom_output_id output_id; /**< External output id */ + eom_output_attribute_e attribute; /**< External output attribute */ + eom_output_attribute_state_e attr_state; /**< External output attribute state */ +} eom_output_notify_attribute_change_s; + +typedef union +{ + eom_output_notify_base_s base; /**< Base structure for eom notify */ + eom_output_notify_add_s output_add; /**< #EOM_OUTPUT_NOTIFY_ADD notify */ + eom_output_notify_remove_s output_remove; /**< #EOM_OUTPUT_NOTIFY_REMOVE notify */ + eom_output_notify_mode_change_s mode_change; /**< #EOM_OUTPUT_NOTIFY_MODE_CHANGED notify */ + eom_output_notify_attribute_change_s attr_change; /**< #EOM_OUTPUT_NOTIFY_ATTRIBUTE_CHANGED notify */ +} eom_output_notify_s; + +typedef struct +{ + eom_output_notify_type_e type; + eom_output_added_cb add_func; + eom_output_removed_cb remove_func; + eom_mode_changed_cb mode_change_func; + eom_attribute_changed_cb attribute_change_func; + void *user_data; +} eom_output_notify_cb_info; + +bool eom_debug_on; + +static pthread_mutex_t eom_lock; + +static bool dbus_initialized; +static EomDBusClientMethod dbus_method; + +static GList *cb_info_list; +static GList *output_info_list; + +static void _eom_output_process_notify_cb (void *data, GValueArray *array); +static eom_output_info* _eom_find_output_info (eom_output_id output_id); +static eom_output_info* _eom_alloc_output_info (int output_id, int output_type); +static const char* +TYPE (eom_output_type_e output_type) +{ + switch (output_type) + { + case EOM_OUTPUT_TYPE_VGA: + return "VGA"; + case EOM_OUTPUT_TYPE_DVII: + return "DVII"; + case EOM_OUTPUT_TYPE_DVID: + return "DVID"; + case EOM_OUTPUT_TYPE_DVIA: + return "DVIA"; + case EOM_OUTPUT_TYPE_COMPOSITE: + return "COMPOSITE"; + case EOM_OUTPUT_TYPE_SVIDEO: + return "SVIDEO"; + case EOM_OUTPUT_TYPE_LVDS: + return "LVDS"; + case EOM_OUTPUT_TYPE_COMPONENT: + return "COMPONENT"; + case EOM_OUTPUT_TYPE_9PINDIN: + return "9PINDIN"; + case EOM_OUTPUT_TYPE_DISPLAYPORT: + return "DISPLAYPORT"; + case EOM_OUTPUT_TYPE_HDMIA: + return "HDMIA"; + case EOM_OUTPUT_TYPE_HDMIB: + return "HDMIB"; + case EOM_OUTPUT_TYPE_TV: + return "TV"; + case EOM_OUTPUT_TYPE_EDP: + return "EDP"; + case EOM_OUTPUT_TYPE_VIRTUAL: + return "VIRTUAL"; + case EOM_OUTPUT_TYPE_DSI: + return "DSI"; + default: + return "UNKNOWN"; + } + return "UNKNOWN"; +} + +static void +_eom_get_debug_evn (void) +{ + char *env = getenv("EOM_DEBUG"); + + if(env) + { + eom_debug_on = (atoi(env) > 0) ? true : false; +#ifdef HAVE_DLOG + fprintf (stderr, "eom dlog on\n"); +#else + fprintf (stderr, "eom dlog off\n"); +#endif + INFO ("EOM_DEBUG = %s", env); + } + else + eom_debug_on = 0; +} + +static bool +_eom_mutex_init (void) +{ + static bool init = false; + + if (init) + return true; + + if (pthread_mutex_init (&eom_lock, NULL)) + { + ERRNO ("fail: mutex init"); + return false; + } + + init = true; + + return true; +} + +void +_eom_mutex_lock (void) +{ + if (!_eom_mutex_init ()) + return; + + pthread_mutex_lock (&eom_lock); +} + +void +_eom_mutex_unlock (void) +{ + pthread_mutex_unlock (&eom_lock); +} + +static bool +_eom_dbus_init (void) +{ + if (dbus_initialized) + return true; + + if (!eom_dbus_client_connect ()) + return false; + + snprintf (dbus_method.name, sizeof (dbus_method.name), "%s", "Notify"); + dbus_method.func = _eom_output_process_notify_cb; + dbus_method.data = NULL; + eom_dbus_client_add_method (&dbus_method); + + dbus_initialized = true; + + INFO ("dbus init"); + + return true; +} + +static void +_eom_dbus_deinit (void) +{ + if (!dbus_initialized) + return; + + /* An output instance and a callback can be created and be added only by user. + * If there is cb_info_list, it means that user is still + * watching and interested with eom dbus message. + */ + if (cb_info_list) + return; + + eom_dbus_client_remove_method (&dbus_method); + eom_dbus_client_disconnect (); + + dbus_initialized = false; +} + +static void +_eom_set_output_info_mode (eom_output_info *output_info, int output_mode) +{ + RET_IF_FAIL (output_info != NULL); + + if (output_info->output_mode == output_mode) + return; + + output_info->output_mode = output_mode; +} + +static void +_eom_set_output_attribute (eom_output_info *output_info, eom_output_attribute_e attribute) +{ + RET_IF_FAIL (output_info != NULL); + + output_info->attribute = attribute; +} + +static void +_eom_set_output_attribute_state (eom_output_info *output_info, eom_output_attribute_state_e state) +{ + RET_IF_FAIL (output_info != NULL); + + output_info->state = state; +} + +static void +_eom_set_output_info_size (eom_output_info *output_info, int w, int h) +{ + RET_IF_FAIL (output_info != NULL); + + output_info->width = w; + output_info->height = h; +} + +static void +_eom_set_output_info_phy_size (eom_output_info *output_info, int w_mm, int h_mm) +{ + RET_IF_FAIL (output_info != NULL); + + output_info->mm_width = w_mm; + output_info->mm_height = h_mm; +} + +static void +_eom_reset_output_info (eom_output_info *output_info) +{ + RET_IF_FAIL (output_info != NULL); + + output_info->output_mode = EOM_OUTPUT_MODE_NONE; + output_info->width = 0; + output_info->height = 0; + output_info->mm_width = 0; + output_info->mm_height = 0; +} + +static void +_eom_output_call_notify_cb (eom_output_notify_s *notify) +{ + GList *l; + + for (l = cb_info_list; l; l = g_list_next (l)) + { + eom_output_notify_cb_info *cb_info = (eom_output_notify_cb_info*)l->data; + + if (!cb_info || cb_info->type != notify->base.type) + continue; + + if (notify->base.type == EOM_OUTPUT_NOTIFY_ADD) + { + if (cb_info->add_func == NULL) + continue; + + INFO ("cb_info: type(%d) output_id(%d)", notify->base.type, notify->base.output_id); + + cb_info->add_func (notify->base.output_id, cb_info->user_data); + } + else if (notify->base.type == EOM_OUTPUT_NOTIFY_REMOVE) + { + if (cb_info->remove_func == NULL) + continue; + + INFO ("cb_info: type(%d) output_id(%d)", notify->base.type, notify->base.output_id); + + cb_info->remove_func (notify->base.output_id, cb_info->user_data); + } + else if (notify->base.type == EOM_OUTPUT_NOTIFY_MODE_CHANGED) + { + if (cb_info->mode_change_func == NULL) + continue; + + INFO ("cb_info: type(%d) output_id(%d)", notify->base.type, notify->base.output_id); + + cb_info->mode_change_func (notify->base.output_id, cb_info->user_data); + } + else if (notify->base.type == EOM_OUTPUT_NOTIFY_ATTRIBUTE_CHANGED) + { + if (cb_info->attribute_change_func == NULL) + continue; + + INFO ("cb_info: type(%d) output_id(%d)", notify->base.type, notify->base.output_id); + + cb_info->attribute_change_func (notify->base.output_id, cb_info->user_data); + } + else + { + INFO ("cb_info: type(%d) output_id(%d)", notify->base.type, notify->base.output_id); + continue; + } + } +} + +static void +_eom_output_process_notify_cb (void *data, GValueArray *array) +{ + eom_output_notify_s notify; + eom_output_info *output_info; + int notify_type, output_id, output_type, output_mode, w, h, w_mm, h_mm, pid, attr, state; + GValue *v; + + RET_IF_FAIL (array != NULL); + RET_IF_FAIL (array->n_values == 11); + + /* 11 args 0: notify_type 1:output_id, 2:output_type, 3:output_mode, 4:w, 5:h, 6:w_mm, 7:h_mm, 8:pid, 9:attri, 10:state */ + v = g_value_array_get_nth (array, 0); + notify_type = g_value_get_int (v); + v = g_value_array_get_nth (array, 1); + output_id = g_value_get_int (v); + v = g_value_array_get_nth (array, 2); + output_type = g_value_get_int (v); + v = g_value_array_get_nth (array, 3); + output_mode = g_value_get_int (v); + v = g_value_array_get_nth (array, 4); + w = g_value_get_int (v); + v = g_value_array_get_nth (array, 5); + h = g_value_get_int (v); + v = g_value_array_get_nth (array, 6); + w_mm = g_value_get_int (v); + v = g_value_array_get_nth (array, 7); + h_mm = g_value_get_int (v); + v = g_value_array_get_nth (array, 8); + pid = g_value_get_int (v); + v = g_value_array_get_nth (array, 9); + attr = g_value_get_int (v); + v = g_value_array_get_nth (array, 10); + state = g_value_get_int (v); + + INFO ("notify: %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", + notify_type, output_id, output_type, output_mode, w, h, w_mm, h_mm, pid, attr, state); + + memset (¬ify, 0, sizeof (eom_output_notify_s)); + notify.base.type = notify_type; + notify.base.output_id = output_id; + + _eom_mutex_lock (); + + output_info = _eom_find_output_info (output_id); + GOTO_IF_FAIL (output_info != NULL, exit); + + switch (notify_type) + { + case EOM_OUTPUT_NOTIFY_ADD: + { + INFO ("'%s(%d)' added", TYPE(output_type), output_id); + + _eom_set_output_info_mode (output_info, output_mode); + _eom_set_output_info_size (output_info, w, h); + _eom_set_output_info_phy_size (output_info, w_mm, h_mm); + + _eom_mutex_unlock (); + _eom_output_call_notify_cb (¬ify); + _eom_mutex_lock (); + } + break; + + case EOM_OUTPUT_NOTIFY_REMOVE: + { + INFO ("'%s(%d)' removed", TYPE(output_type), output_id); + _eom_reset_output_info (output_info); + + _eom_mutex_unlock (); + _eom_output_call_notify_cb (¬ify); + _eom_mutex_lock (); + } + break; + + case EOM_OUTPUT_NOTIFY_MODE_CHANGED: + { + eom_output_mode_e old_mode; + + old_mode = output_info->output_mode; + output_info->output_mode = output_mode; + + INFO ("'%s(%d)' mode changed(%d=>%d)", + TYPE(output_type), output_id, old_mode, output_info->output_mode); + + notify.mode_change.old_mode = old_mode; + notify.mode_change.new_mode = output_info->output_mode; + + _eom_mutex_unlock (); + _eom_output_call_notify_cb (¬ify); + _eom_mutex_lock (); + } + break; + + case EOM_OUTPUT_NOTIFY_ATTRIBUTE_CHANGED: + { + int current_pid = getpid(); + + if (current_pid == pid) + { + INFO ("'%s(%d)'pid(%d)", TYPE(output_type), output_id, pid); + _eom_set_output_attribute(output_info, attr); + _eom_set_output_attribute_state(output_info, state); + notify.attr_change.output_id = output_id; + notify.attr_change.attribute = attr; + notify.attr_change.attr_state = state; + + _eom_mutex_unlock (); + _eom_output_call_notify_cb (¬ify); + _eom_mutex_lock (); + } + } + break; + + default: + INFO ("'unknown(%d)' notified", notify.base.type); + + _eom_mutex_unlock (); + _eom_output_call_notify_cb (¬ify); + _eom_mutex_lock (); + break; + } + +exit: + _eom_mutex_unlock (); +} + + +static eom_output_info* +_eom_find_output_info (eom_output_id output_id) +{ + GList *l; + + for (l = output_info_list; l; l = g_list_next (l)) + { + eom_output_info *output_info = (eom_output_info*)l->data; + + if (output_info && (output_id == output_info->id)) + return output_info; + } + + return NULL; +} + +static void +_eom_free_output_info (eom_output_info **output_info) +{ + if (output_info && *output_info) + { + free(*output_info); + *output_info = NULL; + } +} + +static eom_output_info* +_eom_alloc_output_info (int output_id, int output_type) +{ + eom_output_info *output_info = NULL; + + output_info = calloc (1, sizeof (eom_output_info)); + GOTO_IF_FAIL (output_info != NULL, fail); + + output_info->id = output_id; + output_info->type = output_type; + output_info->output_mode = EOM_OUTPUT_MODE_NONE; + output_info->attribute = EOM_OUTPUT_ATTRIBUTE_NONE; + output_info->state = EOM_OUTPUT_ATTRIBUTE_STATE_NONE; + output_info->width = 0; + output_info->height = 0; + output_info->mm_width = 0; + output_info->mm_height = 0; + + INFO ("alloc '%s(%d)''s info", TYPE (output_type), output_id); + + return output_info; + +fail: + if (output_info) + free (output_info); + + ERR ("fail: alloc '%s(%d)''s info", TYPE (output_type), output_id); + + return NULL; +} + +API int +eom_init (void) +{ + bool ret; + + _eom_get_debug_evn (); + + _eom_mutex_lock (); + + g_type_init (); + + ret = _eom_dbus_init (); + + _eom_mutex_unlock (); + + INFO ("eom init %s", (ret)?"success":"failed"); + + return (ret)?EOM_ERROR_NONE:EOM_ERROR_CONNECTION_FAILURE; +} + +API void +eom_deinit (void) +{ + GList *l; + + _eom_mutex_lock (); + _eom_dbus_deinit (); + + // TODO: redesign the life-cycle of output_infos + //destory output_info. + for (l = output_info_list; l; l = g_list_next (l)) + { + eom_output_info *output_info = (eom_output_info*)l->data; + output_info_list = g_list_remove (output_info_list, output_info); + + _eom_free_output_info(&output_info); + } + + _eom_mutex_unlock (); + + INFO ("eom deinit"); +} + +API eom_output_id* +eom_get_eom_output_ids (int *count) +{ + GValueArray *ret_array = NULL; + eom_output_id *output_ids = NULL; + int i; + + if (!count) + { + set_last_result (EOM_ERROR_INVALID_PARAMETER); + return NULL; + } + + _eom_mutex_lock (); + + ret_array = eom_dbus_client_send_message ("GetOutputIDs", NULL); + + if (!ret_array) + { + *count = 0; + _eom_mutex_unlock (); + set_last_result (EOM_ERROR_NONE); + return NULL; + } + + if (ret_array->n_values == 0) + { + g_value_array_free (ret_array); + *count = 0; + _eom_mutex_unlock (); + set_last_result (EOM_ERROR_NONE); + return NULL; + } + + output_ids = calloc (ret_array->n_values, sizeof (eom_output_id)); + GOTO_IF_FAIL (output_ids != NULL, fail); + + *count = ret_array->n_values; + for (i = 0; i < ret_array->n_values; i++) + { + GValue *v = g_value_array_get_nth (ret_array, i); + output_ids[i] = g_value_get_int (v); + INFO ("output_ids: %d", output_ids[i]); + } + + g_value_array_free (ret_array); + ret_array = NULL; + + // TODO: redesign the life-cycle of output_infos + for (i = 0; i < *count; i++) + { + /* add output_info to output_info_list */ + eom_output_info *output_info; + eom_output_id output_id = output_ids[i]; + GValueArray *msg_array; + GValue v = G_VALUE_INIT; + + output_info = _eom_find_output_info (output_id); + if (output_info) + continue; + + msg_array = g_value_array_new (0); + + g_value_init (&v, G_TYPE_INT); + g_value_set_int (&v, output_id); + msg_array = g_value_array_append (msg_array, &v); + + ret_array = eom_dbus_client_send_message("GetOutputInfo", msg_array); + g_value_array_free (msg_array); + + if (ret_array) + { + /* 0:output_id, 1:output_type, 2:output_mode, 3:w, 4:h, 5:w_mm, 6:h_mm */ + output_info = _eom_alloc_output_info (g_value_get_int(g_value_array_get_nth (ret_array, 0)), + g_value_get_int(g_value_array_get_nth (ret_array, 1))); + if (output_info) + { + output_info_list = g_list_append (output_info_list, output_info); + _eom_set_output_info_mode (output_info, g_value_get_int(g_value_array_get_nth (ret_array, 2))); + _eom_set_output_info_size (output_info, g_value_get_int(g_value_array_get_nth (ret_array, 3)), + g_value_get_int(g_value_array_get_nth (ret_array, 4))); + _eom_set_output_info_phy_size (output_info, g_value_get_int(g_value_array_get_nth (ret_array, 5)), + g_value_get_int(g_value_array_get_nth (ret_array, 6))); + INFO ("GetOutputInfo: %s(%d)", TYPE (output_info->type), output_info->id); + } + + g_value_array_free (ret_array); + ret_array = NULL; + } + else + ERR ("fail: get id(%d)'s information", output_id); + } + + _eom_mutex_unlock (); + + set_last_result (EOM_ERROR_NONE); + + return output_ids; + +fail: + if (ret_array) + g_value_array_free (ret_array); + + if (output_ids) + free (output_ids); + + *count = 0; + + _eom_mutex_unlock (); + + set_last_result (EOM_ERROR_OUT_OF_MEMORY); + + return NULL; +} + +API int +eom_set_output_added_cb (eom_output_added_cb callback, void *user_data) +{ + eom_output_notify_cb_info *cb_info; + GList *l; + + RETV_IF_FAIL (callback != NULL, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + for (l = cb_info_list; l; l = g_list_next (l)) + { + eom_output_notify_cb_info *cb_info = (eom_output_notify_cb_info*)l->data; + + if (cb_info && (cb_info->add_func != NULL) && (cb_info->add_func == callback)) + { + _eom_mutex_unlock (); + return EOM_ERROR_NONE; + } + } + + cb_info = calloc (1, sizeof (eom_output_notify_cb_info)); + GOTO_IF_FAIL (cb_info != NULL, fail); + + cb_info->type = EOM_OUTPUT_NOTIFY_ADD; + cb_info->add_func = callback; + cb_info->user_data = user_data; + + cb_info_list = g_list_append (cb_info_list, cb_info); + + _eom_mutex_unlock (); + + return EOM_ERROR_NONE; + +fail: + _eom_mutex_unlock (); + + return EOM_ERROR_OUT_OF_MEMORY; +} + +API int +eom_unset_output_added_cb (eom_output_added_cb callback) +{ + GList *l; + + RETV_IF_FAIL (callback != NULL, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + for (l = cb_info_list; l; l = g_list_next (l)) + { + eom_output_notify_cb_info *cb_info = (eom_output_notify_cb_info*)l->data; + + if (!cb_info || (cb_info->add_func == NULL) || (cb_info->add_func != callback)) + continue; + + cb_info_list = g_list_remove (cb_info_list, cb_info); + free (cb_info); + + _eom_mutex_unlock (); + + return EOM_ERROR_NONE; + } + + _eom_mutex_unlock (); + + return EOM_ERROR_INVALID_PARAMETER; +} + +API int +eom_set_output_removed_cb (eom_output_removed_cb callback, void *user_data) +{ + eom_output_notify_cb_info *cb_info; + GList *l; + + RETV_IF_FAIL (callback != NULL, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + for (l = cb_info_list; l; l = g_list_next (l)) + { + eom_output_notify_cb_info *cb_info = (eom_output_notify_cb_info*)l->data; + + if (cb_info && (cb_info->remove_func != NULL) && (cb_info->remove_func == callback)) + { + _eom_mutex_unlock (); + return EOM_ERROR_NONE; + } + } + + cb_info = calloc (1, sizeof (eom_output_notify_cb_info)); + GOTO_IF_FAIL (cb_info != NULL, fail); + + cb_info->type = EOM_OUTPUT_NOTIFY_REMOVE; + cb_info->remove_func = callback; + cb_info->user_data = user_data; + + cb_info_list = g_list_append (cb_info_list, cb_info); + + _eom_mutex_unlock (); + + return EOM_ERROR_NONE; + +fail: + _eom_mutex_unlock (); + + return EOM_ERROR_OUT_OF_MEMORY; +} + +API int +eom_unset_output_removed_cb (eom_output_removed_cb callback) +{ + GList *l; + + RETV_IF_FAIL (callback != NULL, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + for (l = cb_info_list; l; l = g_list_next (l)) + { + eom_output_notify_cb_info *cb_info = (eom_output_notify_cb_info*)l->data; + + if (!cb_info || (cb_info->remove_func == NULL) || (cb_info->remove_func != callback)) + continue; + + cb_info_list = g_list_remove (cb_info_list, cb_info); + free (cb_info); + + _eom_mutex_unlock (); + + return EOM_ERROR_NONE; + } + + _eom_mutex_unlock (); + + return EOM_ERROR_INVALID_PARAMETER; +} + +API int +eom_set_mode_changed_cb (eom_mode_changed_cb callback, void *user_data) +{ + eom_output_notify_cb_info *cb_info; + GList *l; + + RETV_IF_FAIL (callback != NULL, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + for (l = cb_info_list; l; l = g_list_next (l)) + { + eom_output_notify_cb_info *cb_info = (eom_output_notify_cb_info*)l->data; + + if (cb_info && (cb_info->mode_change_func != NULL) && (cb_info->mode_change_func == callback)) + { + _eom_mutex_unlock (); + return EOM_ERROR_NONE; + } + } + + cb_info = calloc (1, sizeof (eom_output_notify_cb_info)); + GOTO_IF_FAIL (cb_info != NULL, fail); + + cb_info->type = EOM_OUTPUT_NOTIFY_MODE_CHANGED; + cb_info->mode_change_func = callback; + cb_info->user_data = user_data; + + cb_info_list = g_list_append (cb_info_list, cb_info); + + _eom_mutex_unlock (); + + return EOM_ERROR_NONE; + +fail: + _eom_mutex_unlock (); + + return EOM_ERROR_OUT_OF_MEMORY; +} + +API int +eom_unset_mode_changed_cb (eom_mode_changed_cb callback) +{ + GList *l; + + RETV_IF_FAIL (callback != NULL, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + for (l = cb_info_list; l; l = g_list_next (l)) + { + eom_output_notify_cb_info *cb_info = (eom_output_notify_cb_info*)l->data; + + if (!cb_info || (cb_info->mode_change_func == NULL) || (cb_info->mode_change_func != callback)) + continue; + + cb_info_list = g_list_remove (cb_info_list, cb_info); + free (cb_info); + + _eom_mutex_unlock (); + + return EOM_ERROR_NONE; + } + + _eom_mutex_unlock (); + + return EOM_ERROR_INVALID_PARAMETER; +} + +API int +eom_set_attribute_changed_cb (eom_attribute_changed_cb callback, void *user_data) +{ + eom_output_notify_cb_info *cb_info; + GList *l; + + RETV_IF_FAIL (callback != NULL, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + for (l = cb_info_list; l; l = g_list_next (l)) + { + eom_output_notify_cb_info *cb_info = (eom_output_notify_cb_info*)l->data; + + if (cb_info && (cb_info->attribute_change_func != NULL) && (cb_info->attribute_change_func == callback)) + { + _eom_mutex_unlock (); + return EOM_ERROR_NONE; + } + } + + cb_info = calloc (1, sizeof (eom_output_notify_cb_info)); + GOTO_IF_FAIL (cb_info != NULL, fail); + + cb_info->type = EOM_OUTPUT_NOTIFY_ATTRIBUTE_CHANGED; + cb_info->attribute_change_func = callback; + cb_info->user_data = user_data; + + cb_info_list = g_list_append (cb_info_list, cb_info); + + _eom_mutex_unlock (); + + return EOM_ERROR_NONE; + +fail: + _eom_mutex_unlock (); + + return EOM_ERROR_OUT_OF_MEMORY; +} + +API int +eom_unset_attribute_changed_cb (eom_attribute_changed_cb callback) +{ + GList *l; + + RETV_IF_FAIL (callback != NULL, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + for (l = cb_info_list; l; l = g_list_next (l)) + { + eom_output_notify_cb_info *cb_info = (eom_output_notify_cb_info*)l->data; + + if (!cb_info || (cb_info->attribute_change_func == NULL) || (cb_info->attribute_change_func != callback)) + continue; + + cb_info_list = g_list_remove (cb_info_list, cb_info); + free (cb_info); + + _eom_mutex_unlock (); + + return EOM_ERROR_NONE; + } + + _eom_mutex_unlock (); + + return EOM_ERROR_INVALID_PARAMETER; +} + +API int +eom_set_output_attribute (eom_output_id output_id, eom_output_attribute_e attr) +{ + bool ret = false; + GValueArray *msg_array; + GValueArray *ret_array; + GValue v = G_VALUE_INIT; + int pid = 0; + + RETV_IF_FAIL (output_id != 0, EOM_ERROR_INVALID_PARAMETER); + RETV_IF_FAIL (attr > EOM_OUTPUT_ATTRIBUTE_NONE, EOM_ERROR_INVALID_PARAMETER); + RETV_IF_FAIL (attr < EOM_OUTPUT_ATTRIBUTE_MAX, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + pid = getpid(); + + INFO ("output_id: %d, pid: %d, mode: %d\n", output_id, pid, attr); + + msg_array = g_value_array_new (0); + + /* 0:output_id, 1:pid, 2:eom_attribuete_e */ + g_value_init (&v, G_TYPE_INT); + g_value_set_int (&v, output_id); + msg_array = g_value_array_append (msg_array, &v); + g_value_set_int (&v, pid); + msg_array = g_value_array_append (msg_array, &v); + g_value_set_int (&v, attr); + msg_array = g_value_array_append (msg_array, &v); + + ret_array = eom_dbus_client_send_message ("SetOutputAttribute", msg_array); + g_value_array_free (msg_array); + if (!ret_array) + { + _eom_mutex_unlock (); + return EOM_ERROR_MESSAGE_SENDING_FAILURE; + } + + ret = g_value_get_int (g_value_array_get_nth (ret_array, 0)); + + g_value_array_free (ret_array); + + INFO ("SetOutputAttribute: %s", (ret)?"success":"failed"); + + _eom_mutex_unlock (); + + return (ret)?EOM_ERROR_NONE:EOM_ERROR_MESSAGE_OPERATION_FAILURE; +} + + +API int +eom_get_output_type (eom_output_id output_id, eom_output_type_e *type) +{ + eom_output_info *output_info = NULL; + + RETV_IF_FAIL (output_id != 0, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + output_info = _eom_find_output_info (output_id); + if (!output_info) + { + *type = EOM_OUTPUT_TYPE_UNKNOWN; + _eom_mutex_unlock (); + set_last_result (EOM_ERROR_NO_SUCH_DEVICE); + return EOM_ERROR_NO_SUCH_DEVICE; + } + *type = output_info->type; + + _eom_mutex_unlock (); + + set_last_result (EOM_ERROR_NONE); + return EOM_ERROR_NONE; +} + +API int +eom_get_output_mode (eom_output_id output_id, eom_output_mode_e *mode) +{ + eom_output_info *output_info = NULL; + + RETV_IF_FAIL (output_id != 0, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + output_info = _eom_find_output_info (output_id); + if (!output_info) + { + *mode = EOM_OUTPUT_MODE_NONE; + _eom_mutex_unlock (); + set_last_result (EOM_ERROR_NO_SUCH_DEVICE); + return EOM_ERROR_NO_SUCH_DEVICE; + } + *mode = output_info->output_mode; + + _eom_mutex_unlock (); + + set_last_result (EOM_ERROR_NONE); + return EOM_ERROR_NONE; +} + +API int +eom_get_output_attribute (eom_output_id output_id, eom_output_attribute_e *attribute) +{ + eom_output_info *output_info = NULL; + + RETV_IF_FAIL (output_id != 0, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + output_info = _eom_find_output_info (output_id); + if (!output_info) + { + *attribute = EOM_OUTPUT_ATTRIBUTE_NONE; + _eom_mutex_unlock (); + set_last_result (EOM_ERROR_NO_SUCH_DEVICE); + return EOM_ERROR_NO_SUCH_DEVICE; + } + *attribute = output_info->attribute; + + _eom_mutex_unlock (); + + set_last_result (EOM_ERROR_NONE); + return EOM_ERROR_NONE; +} + +API int +eom_get_output_attribute_state (eom_output_id output_id, eom_output_attribute_state_e *state) +{ + eom_output_info *output_info = NULL; + + RETV_IF_FAIL (output_id != 0, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + output_info = _eom_find_output_info (output_id); + if (!output_info) + { + *state = EOM_OUTPUT_ATTRIBUTE_STATE_NONE; + _eom_mutex_unlock (); + set_last_result (EOM_ERROR_NO_SUCH_DEVICE); + return EOM_ERROR_NO_SUCH_DEVICE; + } + *state = output_info->state; + + _eom_mutex_unlock (); + + set_last_result (EOM_ERROR_NONE); + return EOM_ERROR_NONE; +} + +API int +eom_get_output_resolution (eom_output_id output_id, int *width, int *height) +{ + eom_output_info *output_info = NULL; + + RETV_IF_FAIL (output_id != 0, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + output_info = _eom_find_output_info (output_id); + if (!output_info) + { + if (width) + *width = 0; + if (height) + *height = 0; + + set_last_result (EOM_ERROR_NO_SUCH_DEVICE); + _eom_mutex_unlock (); + return EOM_ERROR_NO_SUCH_DEVICE; + } + + if (width) + *width = output_info->width; + if (height) + *height = output_info->height; + + _eom_mutex_unlock (); + + return EOM_ERROR_NONE; +} + +API int +eom_get_output_physical_size (eom_output_id output_id, int *phy_width, int *phy_height) +{ + eom_output_info *output_info = NULL; + + RETV_IF_FAIL (output_id != 0, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + output_info = _eom_find_output_info (output_id); + if (!output_info) + { + if (phy_width) + *phy_width = 0; + if (phy_height) + *phy_height = 0; + + _eom_mutex_unlock (); + set_last_result (EOM_ERROR_NO_SUCH_DEVICE); + return EOM_ERROR_NO_SUCH_DEVICE; + } + + if (phy_width) + *phy_width = output_info->mm_width; + if (phy_height) + *phy_height = output_info->mm_height; + + _eom_mutex_unlock (); + + return EOM_ERROR_NONE; +} + +API int +eom_set_output_window (eom_output_id output_id, Evas_Object *win) +{ + bool ret = false; + GValueArray *msg_array; + GValueArray *ret_array; + GValue v = G_VALUE_INIT; + Ecore_X_Window xwin; + int pid = 0; + + RETV_IF_FAIL (output_id != 0, EOM_ERROR_INVALID_PARAMETER); + RETV_IF_FAIL (win != NULL, EOM_ERROR_INVALID_PARAMETER); + + _eom_mutex_lock (); + + pid = getpid(); + xwin = elm_win_xwindow_get (win); + + INFO ("output_id: %d, pid: %d, xwin: %d\n", output_id, pid, xwin); + + msg_array = g_value_array_new (0); + + /* 0:output_id, 1:pid, 2:eom_attribuete_e */ + g_value_init (&v, G_TYPE_INT); + g_value_set_int (&v, output_id); + msg_array = g_value_array_append (msg_array, &v); + g_value_set_int (&v, pid); + msg_array = g_value_array_append (msg_array, &v); + g_value_set_int (&v, xwin); + msg_array = g_value_array_append (msg_array, &v); + + ret_array = eom_dbus_client_send_message ("SetWindow", msg_array); + g_value_array_free (msg_array); + if (!ret_array) + { + _eom_mutex_unlock (); + return EOM_ERROR_MESSAGE_SENDING_FAILURE; + } + + ret = g_value_get_int (g_value_array_get_nth (ret_array, 0)); + + g_value_array_free (ret_array); + + if (ret == 1) + { + const char *profile = "desktop"; + elm_win_profiles_set(win, &profile, 1); + elm_win_fullscreen_set (win, EINA_TRUE); + INFO ("SetWindow: success\n"); + _eom_mutex_unlock (); + return EOM_ERROR_NONE; + } + + + INFO ("SetWindow: failed\n"); + _eom_mutex_unlock (); + + return EOM_ERROR_MESSAGE_OPERATION_FAILURE; +} + diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..1829456 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,12 @@ +AM_CFLAGS = \ + $(LIBEOM_CFLAGS) \ + -I$(top_srcdir)/include + +AM_LDFLAGS = \ + $(LIBEOM_LIBS) \ + $(top_builddir)/src/libeom.la + +noinst_PROGRAMS = \ + eom-test-output + +eom_test_output_SOURCES = eom-test-output.c diff --git a/tests/eom-test-output.c b/tests/eom-test-output.c new file mode 100755 index 0000000..f48554d --- /dev/null +++ b/tests/eom-test-output.c @@ -0,0 +1,88 @@ +#include <stdio.h> +#include <stdlib.h> +#include <gio/gio.h> +#include <eom.h> + +/* This test application consider only one output */ + +static void +test_eom_output_notify_cb_output_add (eom_output_notify_s *notify, void *user_data) +{ + eom_output_notify_add_s *add_notify = (eom_output_notify_add_s*)notify; + printf ("output(%d) connected\n", add_notify->output_id); + + /* already has one connected output */ + if (output) + return; + + output = eom_output_create (add_notify->output_id); + if (!output) + printf ("fail: creating output\n"); +} + +static void +test_eom_output_notify_cb_output_remove (eom_output_notify_s *notify, void *user_data) +{ + eom_output_notify_remove_s *rm_notify = (eom_output_notify_remove_s*)notify; + printf ("output(%d) disconnected\n", rm_notify->output_id); + + /* no connected output */ + if (!output) + return; + + if (eom_output_get_output_id (output) != rm_notify->output_id) + { + printf ("I'm not interested in this output(%d,%d)\n", eom_output_get_output_id (output), rm_notify->output_id); + return; + } + + eom_output_destroy (output); + output = NULL; +} + +static void +test_eom_check_connected_output (void) +{ + int output_cnt; + eom_output_id *output_ids; + + output_ids = eom_get_eom_output_ids (&output_cnt); + if (!output_ids) + goto done; + + printf ("output(%d) connected\n", output_ids[0]); + +done: + if (output_ids) + free (output_ids); +} + +int +main(int argc, char *argv[]) +{ + GMainLoop *event_loop; + + g_type_init(); + + if (eom_init ()) + return 0; + + eom_output_add_notify_cb (EOM_OUTPUT_NOTIFY_ADD, test_eom_output_notify_cb_output_add, NULL); + eom_output_add_notify_cb (EOM_OUTPUT_NOTIFY_REMOVE, test_eom_output_notify_cb_output_remove, NULL); + + test_eom_check_connected_output (); + + /* run event loop */ + event_loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (event_loop); + + if (output) + eom_output_destroy (output); + + eom_output_remove_notify_cb (test_eom_output_notify_cb_output_add); + eom_output_remove_notify_cb (test_eom_output_notify_cb_output_remove); + + eom_deinit (); + + return 0; +}
\ No newline at end of file |