From 90907ed4f533b06e121f7d143294c5c453e9b40d Mon Sep 17 00:00:00 2001 From: "jk7744.park" Date: Mon, 26 Oct 2015 15:49:55 +0900 Subject: [PATCH] tizen 2.4 release --- AUTHORS | 3 + COPYING | 25 + COPYING.Flora | 214 +++ Makefile.am | 18 + autogen.sh | 10 + configure.ac | 102 ++ e17-mod-tizen-devicemgr.efl | 7 + e17-mod-tizen-devicemgr.manifest | 5 + module.desktop.in | 31 + packaging/e17-mod-tizen-devicemgr.spec | 69 + src/Makefile.am | 30 + src/e_devicemgr_privates.h | 53 + src/e_mod_config.c | 97 ++ src/e_mod_config.h | 11 + src/e_mod_drv.c | 131 ++ src/e_mod_drv.h | 9 + src/e_mod_main.c | 2866 ++++++++++++++++++++++++++++++++ src/e_mod_main.h | 309 ++++ src/e_mod_scrnconf.c | 1036 ++++++++++++ src/e_mod_scrnconf.h | 36 + src/hib_devicemgr.c | 57 + src/hib_devicemgr.h | 16 + src/rotation_devicemgr.c | 406 +++++ src/rotation_devicemgr.h | 7 + src/scrnconf_devicemgr.c | 63 + src/scrnconf_devicemgr.h | 36 + src/virt_monitor_devicemgr.c | 60 + src/virt_monitor_devicemgr.h | 16 + 28 files changed, 5723 insertions(+) create mode 100755 AUTHORS create mode 100755 COPYING create mode 100755 COPYING.Flora create mode 100755 Makefile.am create mode 100755 autogen.sh create mode 100755 configure.ac create mode 100755 e17-mod-tizen-devicemgr.efl create mode 100644 e17-mod-tizen-devicemgr.manifest create mode 100755 module.desktop.in create mode 100755 packaging/e17-mod-tizen-devicemgr.spec create mode 100755 src/Makefile.am create mode 100755 src/e_devicemgr_privates.h create mode 100755 src/e_mod_config.c create mode 100755 src/e_mod_config.h create mode 100755 src/e_mod_drv.c create mode 100644 src/e_mod_drv.h create mode 100644 src/e_mod_main.c create mode 100644 src/e_mod_main.h create mode 100755 src/e_mod_scrnconf.c create mode 100755 src/e_mod_scrnconf.h create mode 100755 src/hib_devicemgr.c create mode 100644 src/hib_devicemgr.h create mode 100755 src/rotation_devicemgr.c create mode 100755 src/rotation_devicemgr.h create mode 100644 src/scrnconf_devicemgr.c create mode 100755 src/scrnconf_devicemgr.h create mode 100755 src/virt_monitor_devicemgr.c create mode 100644 src/virt_monitor_devicemgr.h diff --git a/AUTHORS b/AUTHORS new file mode 100755 index 0000000..dca1907 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,3 @@ +Sung-Jin Park +SooChan Lim +Sangjin Lee diff --git a/COPYING b/COPYING new file mode 100755 index 0000000..f3bbff3 --- /dev/null +++ b/COPYING @@ -0,0 +1,25 @@ +Copyright notice for Enlightenment: + +Copyright (C) 2000-2012 Carsten Haitzler and various contributors (see AUTHORS) + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/COPYING.Flora b/COPYING.Flora new file mode 100755 index 0000000..674651d --- /dev/null +++ b/COPYING.Flora @@ -0,0 +1,214 @@ +Copyright notice for Flora-licensed files: + +The following file is copyrighted by Samsung Electronics Co., Ltd +and licensed under Flora License, Version 1.1 +- devicemgr/src/rotation_devicemgr.c + +Copyright (C) 2013 Samsung Electronics Co., Ltd All rights reserved. + +Flora License + +Version 1.1, April, 2013 + +http://floralicense.org/license/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, +and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by +the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and +all other entities that control, are controlled by, or are +under common control with that entity. For the purposes of +this definition, "control" means (i) the power, direct or indirect, +to cause the direction or management of such entity, +whether by contract or otherwise, or (ii) ownership of fifty percent (50%) +or more of the outstanding shares, or (iii) beneficial ownership of +such entity. + +"You" (or "Your") shall mean an individual or Legal Entity +exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, +including but not limited to software source code, documentation source, +and configuration files. + +"Object" form shall mean any form resulting from mechanical +transformation or translation of a Source form, including but +not limited to compiled object code, generated documentation, +and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, +made available under the License, as indicated by a copyright notice +that is included in or attached to the work (an example is provided +in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, +that is based on (or derived from) the Work and for which the editorial +revisions, annotations, elaborations, or other modifications represent, +as a whole, an original work of authorship. For the purposes of this License, +Derivative Works shall not include works that remain separable from, +or merely link (or bind by name) to the interfaces of, the Work and +Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original +version of the Work and any modifications or additions to that Work or +Derivative Works thereof, that is intentionally submitted to Licensor +for inclusion in the Work by the copyright owner or by an individual or +Legal Entity authorized to submit on behalf of the copyright owner. +For the purposes of this definition, "submitted" means any form of +electronic, verbal, or written communication sent to the Licensor or +its representatives, including but not limited to communication on +electronic mailing lists, source code control systems, and issue +tracking systems that are managed by, or on behalf of, the Licensor +for the purpose of discussing and improving the Work, but excluding +communication that is conspicuously marked or otherwise designated +in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity +on behalf of whom a Contribution has been received by Licensor and +subsequently incorporated within the Work. + +"Tizen Certified Platform" shall mean a software platform that complies +with the standards set forth in the Tizen Compliance Specification +and passes the Tizen Compliance Tests as defined from time to time +by the Tizen Technical Steering Group and certified by the Tizen +Association or its designated agent. + +2. Grant of Copyright License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the +Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +(except as stated in this section) patent license to make, have made, +use, offer to sell, sell, import, and otherwise transfer the Work +solely as incorporated into a Tizen Certified Platform, where such +license applies only to those patent claims licensable by such +Contributor that are necessarily infringed by their Contribution(s) +alone or by combination of their Contribution(s) with the Work solely +as incorporated into a Tizen Certified Platform to which such +Contribution(s) was submitted. If You institute patent litigation +against any entity (including a cross-claim or counterclaim +in a lawsuit) alleging that the Work or a Contribution incorporated +within the Work constitutes direct or contributory patent infringement, +then any patent licenses granted to You under this License for that +Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the +Work or Derivative Works thereof pursuant to the copyright license +above, in any medium, with or without modifications, and in Source or +Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works + a copy of this License; and + 2. You must cause any modified files to carry prominent notices stating + that You changed the files; and + 3. You must retain, in the Source form of any Derivative Works that + You distribute, all copyright, patent, trademark, and attribution + notices from the Source form of the Work, excluding those notices + that do not pertain to any part of the Derivative Works; and + 4. If the Work includes a "NOTICE" text file as part of its distribution, + then any Derivative Works that You distribute must include a readable + copy of the attribution notices contained within such NOTICE file, + excluding those notices that do not pertain to any part of + the Derivative Works, in at least one of the following places: + within a NOTICE text file distributed as part of the Derivative Works; + within the Source form or documentation, if provided along with the + Derivative Works; or, within a display generated by the Derivative Works, + if and wherever such third-party notices normally appear. + The contents of the NOTICE file are for informational purposes only + and do not modify the License. You may add Your own attribution notices + within Derivative Works that You distribute, alongside or as an addendum + to the NOTICE text from the Work, provided that such additional attribution + notices cannot be construed as modifying the License. You may add Your own + copyright statement to Your modifications and may provide additional or + different license terms and conditions for use, reproduction, or + distribution of Your modifications, or for any such Derivative Works + as a whole, provided Your use, reproduction, and distribution of + the Work otherwise complies with the conditions stated in this License + and your own copyright statement or terms and conditions do not conflict + the conditions stated in the License including section 3. + +5. Submission of Contributions. Unless You explicitly state otherwise, +any Contribution intentionally submitted for inclusion in the Work +by You to the Licensor shall be under the terms and conditions of +this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify +the terms of any separate license agreement you may have executed +with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade +names, trademarks, service marks, or product names of the Licensor, +except as required for reasonable and customary use in describing the +origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or +agreed to in writing, Licensor provides the Work (and each +Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied, including, without limitation, any warranties or conditions +of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +PARTICULAR PURPOSE. You are solely responsible for determining the +appropriateness of using or redistributing the Work and assume any +risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, +whether in tort (including negligence), contract, or otherwise, +unless required by applicable law (such as deliberate and grossly +negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, +incidental, or consequential damages of any character arising as a +result of this License or out of the use or inability to use the +Work (including but not limited to damages for loss of goodwill, +work stoppage, computer failure or malfunction, or any and all +other commercial damages or losses), even if such Contributor +has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing +the Work or Derivative Works thereof, You may choose to offer, +and charge a fee for, acceptance of support, warranty, indemnity, +or other liability obligations and/or rights consistent with this +License. However, in accepting such obligations, You may act only +on Your own behalf and on Your sole responsibility, not on behalf +of any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason +of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Flora License to your work + +To apply the Flora License to your work, attach the following +boilerplate notice, with the fields enclosed by brackets "[]" +replaced with your own identifying information. (Don't include +the brackets!) The text should be enclosed in the appropriate +comment syntax for the file format. We also recommend that a +file or class name and description of purpose be included on the +same "printed page" as the copyright notice for easier +identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Flora License, Version 1.1 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://floralicense.org/license/ + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/Makefile.am b/Makefile.am new file mode 100755 index 0000000..61a7736 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,18 @@ +# maintainer-clean removes everything +MAINTAINERCLEANFILES = aclocal.m4 compile config.sub config.guess config.h.in \ + configure depcomp install-sh ltmain.sh Makefile.in missing + +SUBDIRS = src + +filesdir = $(datadir) +files_DATA = module.desktop + +EXTRA_DIST = module.desktop.in + +clean-local: + rm -rf module.desktop + +uninstall: + rm -rf $(DESTDIR)$(datadir) + + diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..5a30991 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. + +set -x +aclocal +autoconf +libtoolize --copy --force +autoheader +automake --foreign --add-missing --copy + diff --git a/configure.ac b/configure.ac new file mode 100755 index 0000000..db74277 --- /dev/null +++ b/configure.ac @@ -0,0 +1,102 @@ +# authored by Sung-Jin Park +# +# Note ) +# +# AC_DEFINE(VARIABLE, VALUE, DESCRIPTION) +# output the following to config.h +# /* DESCRIPTION */ +# #define VARIABLE VALUE +# +# AC_SUBST(VARIABLE, [VALUE]) +# define $(VARIABLE) as VALUE in Makefile + +dnl ======================================================================== +# initialization +dnl ======================================================================== +AC_INIT([e17-mod-tizen-devicemgr], [0.1], [sj76.park@samsung.com]) + +# check for tools needed by automake generated Makefiles +# -Wall : Turn all warnings on. +# -Werror: report warings as errors. +# foreign: relax some GNU standard requirements +#AM_INIT_AUTOMAKE([-Wall -Werror foreign]) +AM_INIT_AUTOMAKE([-Wall foreign]) + +dnl ======================================================================== +# checks for programs +dnl ======================================================================== +AC_PROG_CC +AC_DISABLE_STATIC +AC_PROG_LIBTOOL + +dnl ======================================================================== +# checks for libraries +dnl ======================================================================== + +dnl ======================================================================== +# checks for header files +dnl ======================================================================== +#AC_HEADER_STDC +AC_CHECK_HEADERS([math.h fcntl.h stdlib.h string.h unistd.h]) + +dnl ======================================================================== +# checks for typedefs, structures, and compiler characteristics +AC_C_CONST + +dnl ======================================================================== +# checks for library functions +dnl ======================================================================== +#AC_FUNC_MALLOC +AC_FUNC_MMAP +AC_CHECK_FUNCS([memset munmap strcasecmp strdup]) + +dnl ======================================================================== +# checks for pkg-config +dnl ======================================================================== +PKG_PROG_PKG_CONFIG + +#PKG_CHECK_MODULES(GESTUREPROTO, gestureproto) +#PKG_CHECK_MODULES(GESTURELIB, xgesture) + +dnl ======================================================================== +# checks for pkg-config +dnl ======================================================================== +#PKG_CHECK_MODULES(ENLIGHTENMENT, [enlightenment, gestureproto, xgesture]) +PKG_CHECK_MODULES(ENLIGHTENMENT, [enlightenment, vconf, dlog, sensor]) +ENLIGHTENMENT_CFLAGS="${ENLIGHTENMENT_CFLAGS} " +AC_SUBST(ENLIGHTENMENT_CFLAGS) +AC_SUBST(ENLIGHTENMENT_LIBS) + + +dnl ======================================================================= + +release=$(pkg-config --variable=release enlightenment) +MODULE_ARCH="$host_os-$host_cpu-$release" +AC_SUBST(MODULE_ARCH) +AC_DEFINE_UNQUOTED(MODULE_ARCH, "$MODULE_ARCH", "Module architecture") + +datadir=$(pkg-config --variable=modules enlightenment)/${PACKAGE} +AC_ARG_ENABLE(homedir-install, + AS_HELP_STRING([--enable-homedir-install], [Install module in homedir]), + [ datadir="${HOME}/.e/e/modules/${PACKAGE}" ] +) + +dnl ======================================================================== +# output files +dnl ======================================================================== + +# create HEADER for all HEADER.in. +# HEADERS contain definitions made with AC_DEFINE. +# the following command will create config.h from config.h.in +AC_CONFIG_HEADERS([config.h]) + +# create FILE for all FILE.in. +# FILES contains definitions made with AC_SUBST. +AC_CONFIG_FILES([ + Makefile + src/Makefile + module.desktop + ]) + +AC_OUTPUT + diff --git a/e17-mod-tizen-devicemgr.efl b/e17-mod-tizen-devicemgr.efl new file mode 100755 index 0000000..ee5f9ef --- /dev/null +++ b/e17-mod-tizen-devicemgr.efl @@ -0,0 +1,7 @@ +e17 system::share rwx--- ------ +e17 e17::notification rw---- ------ +e17 deviced::display rw---- ------ +e17 tizen::vconf::setting::admin rw---- ------ +e17 tizen::vconf::public::r::platform::rw rw---- ------ +e17 tizen::vconf::public::r rw---- ------ +e17 sensord::bio rw---- ------ diff --git a/e17-mod-tizen-devicemgr.manifest b/e17-mod-tizen-devicemgr.manifest new file mode 100644 index 0000000..43b01f5 --- /dev/null +++ b/e17-mod-tizen-devicemgr.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/module.desktop.in b/module.desktop.in new file mode 100755 index 0000000..6004639 --- /dev/null +++ b/module.desktop.in @@ -0,0 +1,31 @@ +[Desktop Entry] +Type=Link +Name=DeviceMgr +Name[cs]= +Name[de]= +Name[eo]= +Name[es]= +Name[fr]= +Name[hu]= +Name[it]= +Name[ja]= +Name[pt]= +Name[pt_BR]= +Name[tr]= +Name[zh_CN]= +Name[zh_TW]= +Icon=e-module-skel +Comment=DeviceMgr
DeviceMgr. +Comment[cs]= +Comment[de]= +Comment[eo]= +Comment[es]= +Comment[fr]= +Comment[hu]= +Comment[it]= +Comment[ja]= +Comment[pt]= +Comment[pt_BR]= +Comment[tr]= +Comment[zh_CN]= +Comment[zh_TW]= diff --git a/packaging/e17-mod-tizen-devicemgr.spec b/packaging/e17-mod-tizen-devicemgr.spec new file mode 100755 index 0000000..dab55a1 --- /dev/null +++ b/packaging/e17-mod-tizen-devicemgr.spec @@ -0,0 +1,69 @@ +Name: e17-mod-tizen-devicemgr +Summary: The E17 Devicemgr Extra Modules for Tizen +Version: 0.1.6 +Release: 1 +Group: System/GUI/Other +License: BSD 2-clause and Flora-1.1 +Source0: %{name}-%{version}.tar.gz +BuildRequires: pkgconfig(enlightenment) +BuildRequires: pkgconfig(utilX) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(x11) +BuildRequires: pkgconfig(xrandr) +BuildRequires: pkgconfig(xi) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(ttrace) +BuildRequires: pkgconfig(sensor) + +Requires: libX11 +Requires: vconf +Requires: libsensord + +%description +The E17 Extra Modules The E17 extra modules consists of modules. + +%prep +%setup -q + + +%build + +export GC_SECTIONS_FLAGS="-fdata-sections -ffunction-sections -Wl,--gc-sections" +export CFLAGS+=" -Wall -g -fPIC -rdynamic -Werror-implicit-function-declaration ${GC_SECTIONS_FLAGS} " +export LDFLAGS+=" -Wl,--hash-style=both -Wl,--as-needed -Wl,--rpath=/usr/lib" +export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" + +#for devicemgr +export CFLAGS+=" -D_F_SUPPORT_XTEST_TOUCH_EVENT_" + +%ifarch %{arm} +export CFLAGS+=" -D_ENV_ARM" +%endif + +%autogen +%configure --prefix=/usr +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} + +# for smack rule +mkdir -p %{buildroot}/etc/smack/accesses.d +cp %{_builddir}/%{buildsubdir}/e17-mod-tizen-devicemgr.efl %{buildroot}/etc/smack/accesses.d + +# for license notification +mkdir -p %{buildroot}/usr/share/license +cp -a %{_builddir}/%{buildsubdir}/COPYING %{buildroot}/usr/share/license/%{name} +cat %{_builddir}/%{buildsubdir}/COPYING.Flora >> %{buildroot}/usr/share/license/%{name} + +make install DESTDIR=%{buildroot} + +find %{buildroot}/usr/lib/enlightenment/modules -name *.la | xargs rm + +%files +%manifest e17-mod-tizen-devicemgr.manifest +%defattr(-,root,root,-) + +%{_libdir}/enlightenment/modules/e17-mod-tizen-devicemgr +/usr/share/license/%{name} +/etc/smack/accesses.d/e17-mod-tizen-devicemgr.efl diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100755 index 0000000..2df6986 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,30 @@ +MAINTAINERCLEANFILES = Makefile.in +MODULE = e17-mod-tizen-devicemgr + +LDFLAGS += + +pkgdir = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH) +pkg_LTLIBRARIES = module.la +module_la_SOURCES = e_mod_main.c \ + e_mod_main.h \ + e_mod_config.c \ + e_mod_config.h \ + e_devicemgr_privates.h \ + e_mod_scrnconf.c \ + e_mod_scrnconf.h \ + scrnconf_devicemgr.c \ + scrnconf_devicemgr.h \ + e_mod_drv.c \ + e_mod_drv.h \ + virt_monitor_devicemgr.h \ + hib_devicemgr.h \ + rotation_devicemgr.c \ + rotation_devicemgr.h + +module_la_LIBADD = +module_la_CFLAGS = @ENLIGHTENMENT_CFLAGS@ +module_la_LDFLAGS = -module -avoid-version @ENLIGHTENMENT_LIBS@ +module_la_DEPENDENCIES = $(top_builddir)/config.h + +#uninstall: +# rm -rf $(DESTDIR)$(libdir)/enlightenment/modules/$(MODULE) diff --git a/src/e_devicemgr_privates.h b/src/e_devicemgr_privates.h new file mode 100755 index 0000000..1ad54bf --- /dev/null +++ b/src/e_devicemgr_privates.h @@ -0,0 +1,53 @@ + +#ifndef _E_DEVICEMGR_PRIVATE_H_ +#define _E_DEVICEMGR_PRIVATE_H_ + +#include "e.h" + +#define LOG_TAG "DEVICEMGR" +#include "dlog.h" + +#define E_DEVICEMGR_CFG "module.e17-mod-tizen-devicemgr" + +/* atoms */ +#define STR_ATOM_DEVICEMGR_CFG "_DEVICEMGR_CFG" + +typedef enum +{ + DEVICEMGR_CFG_POPUP, + DEVICEMGR_CFG_DEFAULT_DISPMODE, +} DEVICEMGR_CFG; + +typedef struct _E_Devicemgr_Config E_Devicemgr_Config; +typedef struct _E_Devicemgr_Config_Rotation E_Devicemgr_Config_Rotation; + +/* external variable to store active config */ +extern E_Devicemgr_Config *_e_devicemgr_cfg; + +/** + * @brief structure for Devicemgr configuration. + * + * @ingroup E_Devicemgr_Config_Group + */ +struct _E_Devicemgr_Config +{ + struct + { + int enable; + /**< enable screen configuration */ + int default_dispmode; + /**< default display mode */ + Eina_Bool isPopUpEnabled; + /**< popup enable/disable status */ + } ScrnConf; + Eina_List *rotation; +}; + +struct _E_Devicemgr_Config_Rotation +{ + Eina_Bool enable; + int angle; +}; + +#endif//_E_DEVICEMGR_PRIVATE_H_ + diff --git a/src/e_mod_config.c b/src/e_mod_config.c new file mode 100755 index 0000000..c6b0450 --- /dev/null +++ b/src/e_mod_config.c @@ -0,0 +1,97 @@ + +#include "e_devicemgr_privates.h" +#include "e_mod_config.h" +#include "scrnconf_devicemgr.h" + +/* local variables */ +static E_Config_DD *_devicemgr_conf_edd = NULL; +static E_Config_DD *_devicemgr_conf_rotation_edd = NULL; + +static void _e_mod_devicemgr_config_free(void); +static void _e_mod_devicemgr_config_new(void); + +/* external variables */ +E_Devicemgr_Config *_e_devicemgr_cfg = NULL; + +int +e_mod_devicemgr_config_init(void) +{ + /* create config structure for module */ + _devicemgr_conf_edd = E_CONFIG_DD_NEW("Devicemgr_Config", E_Devicemgr_Config); + + _devicemgr_conf_rotation_edd = E_CONFIG_DD_NEW("E_Devicemgr_Config_Rotation", + E_Devicemgr_Config_Rotation); +#undef T +#undef D +#define T E_Devicemgr_Config_Rotation +#define D _devicemgr_conf_rotation_edd + E_CONFIG_VAL(D, T, enable, UCHAR); + E_CONFIG_VAL(D, T, angle, INT); + +#undef T +#undef D +#define T E_Devicemgr_Config +#define D _devicemgr_conf_edd + E_CONFIG_VAL(D, T, ScrnConf.enable, UCHAR); + E_CONFIG_VAL(D, T, ScrnConf.default_dispmode, INT); + E_CONFIG_VAL(D, T, ScrnConf.isPopUpEnabled, UCHAR); + E_CONFIG_LIST(D, T, rotation, _devicemgr_conf_rotation_edd); + + /* attempt to load existing configuration */ + _e_devicemgr_cfg = e_config_domain_load(E_DEVICEMGR_CFG, _devicemgr_conf_edd); + + /* create new config if we need to */ + if (!_e_devicemgr_cfg) + { + _e_mod_devicemgr_config_new(); + e_mod_devicemgr_config_save(); + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][config] Config file for e_devicemgr was made/stored !\n"); + } + else + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][config] Config file for e_devicemgr was loaded successfully !\n"); + } + + return 1; +} + +int +e_mod_devicemgr_config_shutdown(void) +{ + /* free config structure */ + _e_mod_devicemgr_config_free(); + + /* free data descriptors */ + E_CONFIG_DD_FREE(_devicemgr_conf_edd); + + return 1; +} + +int +e_mod_devicemgr_config_save(void) +{ + return e_config_domain_save(E_DEVICEMGR_CFG, _devicemgr_conf_edd, _e_devicemgr_cfg); +} + +/* local functions */ +static void +_e_mod_devicemgr_config_free(void) +{ + /* check for config */ + if (!_e_devicemgr_cfg) return; + + /* free config structure */ + E_CONFIG_DD_FREE(_devicemgr_conf_rotation_edd); + E_FREE(_e_devicemgr_cfg); +} + +static void +_e_mod_devicemgr_config_new(void) +{ + /* create initial config */ + _e_devicemgr_cfg = E_NEW(E_Devicemgr_Config, 1); + _e_devicemgr_cfg->ScrnConf.enable = EINA_TRUE; + _e_devicemgr_cfg->ScrnConf.default_dispmode = UTILX_SCRNCONF_DISPMODE_CLONE; + _e_devicemgr_cfg->ScrnConf.isPopUpEnabled = EINA_FALSE; +} + diff --git a/src/e_mod_config.h b/src/e_mod_config.h new file mode 100755 index 0000000..c45b2d1 --- /dev/null +++ b/src/e_mod_config.h @@ -0,0 +1,11 @@ + +#ifndef _E_MOD_CONFIG_H_ +#define _E_MOD_CONFIG_H_ + +/* local function prototypes */ +int e_mod_devicemgr_config_init(void); +int e_mod_devicemgr_config_shutdown(void); +int e_mod_devicemgr_config_save(void); + +#endif//_E_MOD_CONFIG_H_ + diff --git a/src/e_mod_drv.c b/src/e_mod_drv.c new file mode 100755 index 0000000..6df2070 --- /dev/null +++ b/src/e_mod_drv.c @@ -0,0 +1,131 @@ +#include "e.h" +#include "e_randr.h" +#include "e_mod_main.h" +#include "e_mod_drv.h" + +#define STR_XRR_LVDS_FUNCTION "XRR_PROPERTY_LVDS_FUNCTION" + +#ifdef _MAKE_ATOM +# undef _MAKE_ATOM +#endif + +#define _MAKE_ATOM(a, s) \ + do { \ + a = ecore_x_atom_get (s); \ + if (!a) \ + SLOG(LOG_DEBUG, "DEVICEMGR", \ + "[E-devmgr] ##s creation failed.\n"); \ + } while (0) + +/* lvds function */ +typedef enum +{ + XRR_OUTPUT_LVDS_FUNC_NULL, /* null */ + XRR_OUTPUT_LVDS_FUNC_INIT_VIRTUAL, /* virutal output connect/disconnect */ + XRR_OUTPUT_LVDS_FUNC_HIBERNATION, /* hibernation on / off */ + XRR_OUTPUT_LVDS_FUNC_ACCESSIBLILITY, /* accessibility */ +} XRROutputPropLvdsFunc; + + +void +e_mod_drv_virt_mon_set (int cmd) +{ + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: set the virtual output connect/disconnect\n"); + + E_Randr_Output_Info *output_info = NULL; + Eina_List *l_output; + Eina_Bool found_output = EINA_FALSE; + Ecore_X_Randr_Output output_xid[1] = {0}; + Ecore_X_Atom lvds_func; + int value[2]; + + EINA_LIST_FOREACH (e_randr_screen_info.rrvd_info.randr_info_12->outputs, l_output, output_info) + { + if (output_info == NULL) + continue; + + if (!strcmp (output_info->name, "LVDS1")) + { + output_xid[0] = output_info->xid; + found_output = EINA_TRUE; + } + } + + if (!found_output) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: fail to initialize the virtual output\n"); + goto set_fail; + } + + ecore_x_grab (); + + _MAKE_ATOM (lvds_func, STR_XRR_LVDS_FUNCTION); + + value[0] = XRR_OUTPUT_LVDS_FUNC_INIT_VIRTUAL; + value[1] = cmd; + + /* no ecore x API for XRRChangeOutputProperty */ + XRRChangeOutputProperty (ecore_x_display_get (), output_xid[0], lvds_func, XA_INTEGER, 32, + PropModeReplace, (unsigned char *)&value, 2); + + /* replay through XSendMessage */ + + ecore_x_ungrab (); + ecore_x_sync (); + return; + +set_fail: + ecore_x_ungrab (); +} + +void +e_mod_drv_hib_set (int cmd) +{ + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: set the hibernation on/off\n"); + + E_Randr_Output_Info *output_info = NULL; + Eina_List *l_output; + Eina_Bool found_output = EINA_FALSE; + Ecore_X_Randr_Output output_xid[1] = {0}; + Ecore_X_Atom lvds_func; + int value[2]; + + EINA_LIST_FOREACH (e_randr_screen_info.rrvd_info.randr_info_12->outputs, l_output, output_info) + { + if (output_info == NULL) + continue; + + if (!strcmp (output_info->name, "LVDS1")) + { + output_xid[0] = output_info->xid; + found_output = EINA_TRUE; + } + } + + if (!found_output) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: fail to initialize the virtual output\n"); + goto set_fail; + } + + ecore_x_grab (); + + _MAKE_ATOM (lvds_func, STR_XRR_LVDS_FUNCTION); + + value[0] = XRR_OUTPUT_LVDS_FUNC_HIBERNATION; + value[1] = cmd; + + /* no ecore x API for XRRChangeOutputProperty */ + XRRChangeOutputProperty (ecore_x_display_get (), output_xid[0], lvds_func, XA_INTEGER, 32, + PropModeReplace, (unsigned char *)&value, 2); + + /* replay through XSendMessage */ + + ecore_x_ungrab (); + ecore_x_sync (); + return; + +set_fail: + ecore_x_ungrab (); +} + diff --git a/src/e_mod_drv.h b/src/e_mod_drv.h new file mode 100644 index 0000000..ba798a8 --- /dev/null +++ b/src/e_mod_drv.h @@ -0,0 +1,9 @@ +#ifndef E_MOD_DRV_H +#define E_MOD_DRV_H + +void e_mod_drv_virt_mon_set (int cmd); + +void e_mod_drv_hib_set (int cmd); + +#endif // E_MOD_DRV_H + diff --git a/src/e_mod_main.c b/src/e_mod_main.c new file mode 100644 index 0000000..bba2452 --- /dev/null +++ b/src/e_mod_main.c @@ -0,0 +1,2866 @@ + +#include "e.h" +#include "e_devicemgr_privates.h" +#include "e_mod_main.h" +#include "e_mod_config.h" +#include +#include + +#define XSELECTION_HDMI_NAME "HDMI" +#define XSELECTION_TIMEOUT 10.0 + +#define E_MOD_SCRNCONF_CHK(cond) {if (!(cond)) { SLOG(LOG_DEBUG, "DEVICEMGR", "[%s] : '%s' failed.\n", __func__, #cond); }} +#define E_MOD_SCRNCONF_CHK_RET(cond, val) {if (!(cond)) { SLOG(LOG_DEBUG, "DEVICEMGR", "[%s] : '%s' failed.\n", __func__, #cond); return val; }} +#define E_MOD_SCRNCONF_CHK_GOTO(cond, dst) {if (!(cond)) { SLOG(LOG_DEBUG, "DEVICEMGR", "[%s] : '%s' failed.\n", __func__, #cond); goto dst; }} + +extern char *strcasestr(const char *s, const char *find); +DeviceMgr e_devicemgr; +static Eina_Bool e_mod_set_disp_clone = EINA_FALSE; + +static int _e_devicemgr_init (void); +static void _e_devicemgr_fini (void); +static int _e_devicemgr_get_configuration (void); +static int _e_devicemgr_update_configuration (void); + +static int _e_devicemgr_cb_crtc_change (void *data, int type, void *ev); +static int _e_devicemgr_cb_output_change (void *data, int type, void *ev); +static int _e_devicemgr_cb_output_property (void *data, int type, void *ev); +static int _e_devicemgr_cb_client_message (void* data, int type, void* event); + +static Eina_Bool _e_devicemgr_dialog_and_connect (Ecore_X_Randr_Output output_xid); +static Eina_Bool _e_devicemgr_disconnect (Ecore_X_Randr_Output output_xid); +static Eina_Bool _e_devicemgr_selection_clear_cb (void* data, int type, void *event); +static Eina_Bool _e_devicemgr_selection_request_cb (void* data, int type, void *event); +static Eina_Bool _e_devicemgr_selection_notify_cb (void* data, int type, void *event); + +/* this is needed to advertise a label for the module IN the code (not just + * the .desktop file) but more specifically the api version it was compiled + * for so E can skip modules that are compiled for an incorrect API version + * safely) */ +EAPI E_Module_Api e_modapi = +{ + E_MODULE_API_VERSION, + "DeviceMgr Module of Window Manager" +}; + +EAPI void* +e_modapi_init(E_Module* m) +{ + if (!_e_devicemgr_init()) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed @ _e_devicemgr_init()..!\n", __FUNCTION__); + return NULL; + } + + /* add handlers */ + e_devicemgr.client_message_handler = ecore_event_handler_add (ECORE_X_EVENT_CLIENT_MESSAGE, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_client_message, NULL); + e_devicemgr.window_property_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_window_property, NULL); + e_devicemgr.event_generic_handler = ecore_event_handler_add(ECORE_X_EVENT_GENERIC, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_event_generic, NULL); + e_devicemgr.zone_add_handler = ecore_event_handler_add(E_EVENT_ZONE_ADD, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_zone_add, NULL); + e_devicemgr.zone_del_handler = ecore_event_handler_add(E_EVENT_ZONE_DEL, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_zone_del, NULL); + e_devicemgr.window_destroy_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_DESTROY, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_window_destroy, NULL); + + e_devicemgr.e_msg_handler = e_msg_handler_add(_e_mod_move_e_msg_handler, NULL); + + if (!e_devicemgr.window_property_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_WINDOW_PROPERTY handler\n", __FUNCTION__); + if (!e_devicemgr.event_generic_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_GENERIC handler\n", __FUNCTION__); + if (!e_devicemgr.zone_add_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add E_EVENT_ZONE_ADD handler\n", __FUNCTION__); + if (!e_devicemgr.zone_del_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add E_EVENT_ZONE_DEL handler\n", __FUNCTION__); + if (!e_devicemgr.e_msg_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add E_MSG handler\n", __FUNCTION__); + if (!e_devicemgr.window_destroy_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_WINDOW_DESTROY handler\n", __FUNCTION__); +#if 0 + if (e_devicemgr.scrnconf_enable) + { + e_devicemgr.randr_crtc_handler = ecore_event_handler_add (ECORE_X_EVENT_RANDR_CRTC_CHANGE, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_crtc_change, NULL); + e_devicemgr.randr_output_handler = ecore_event_handler_add (ECORE_X_EVENT_RANDR_OUTPUT_CHANGE, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_output_change, NULL); + e_devicemgr.randr_output_property_handler = ecore_event_handler_add (ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_output_property, NULL); + + if (!e_devicemgr.randr_crtc_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_RANDR_CRTC_CHANGE handler\n", __FUNCTION__); + if (!e_devicemgr.randr_output_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_RANDR_OUTPUT_CHANGE handler\n", __FUNCTION__); + if (!e_devicemgr.randr_output_property_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY handler\n", __FUNCTION__); + } +#endif + return m; +} + +EAPI int +e_modapi_shutdown(E_Module* m) +{ + ecore_event_handler_del (e_devicemgr.randr_crtc_handler); + ecore_event_handler_del (e_devicemgr.randr_output_handler); + ecore_event_handler_del (e_devicemgr.randr_output_property_handler); + ecore_event_handler_del(e_devicemgr.window_property_handler); + ecore_event_handler_del(e_devicemgr.event_generic_handler); + ecore_event_handler_del(e_devicemgr.zone_add_handler); + ecore_event_handler_del(e_devicemgr.zone_del_handler); + if (e_devicemgr.e_msg_handler) e_msg_handler_del(e_devicemgr.e_msg_handler); + e_devicemgr.window_property_handler = NULL; + e_devicemgr.event_generic_handler = NULL; + e_devicemgr.zone_add_handler = NULL; + e_devicemgr.zone_del_handler = NULL; + + e_devicemgr.randr_crtc_handler = NULL; + e_devicemgr.randr_output_handler = NULL; + e_devicemgr.randr_output_property_handler = NULL; + _e_devicemgr_fini(); + + return 1; +} + +EAPI int +e_modapi_save(E_Module* m) +{ + /* Do Something */ + return 1; +} + +static int +_e_devicemgr_init(void) +{ + unsigned int val = 1; + int res, ret = 1; + int enable = 1; + int disable = 0; + int no_window = -1; + + memset(&e_devicemgr, 0, sizeof(DeviceMgr)); + + e_devicemgr.disp = ecore_x_display_get(); + + if (!e_devicemgr.disp) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to open display..!\n"); + ret = 0; + goto out; + } + + e_devicemgr.rootWin = ecore_x_window_root_first_get(); + + /* init data structure */ + e_devicemgr.cursor_show = 0; + e_devicemgr.cursor_show_ack = 0; + e_devicemgr.rel_move_deviceid = 0; + e_devicemgr.vcp_id = -1; + e_devicemgr.vcp_xtest_pointer_id = -1; + e_devicemgr.vck_xtest_keyboard_id = -1; + e_devicemgr.new_master_pointer_id = -1; + e_devicemgr.virtual_touchpad_id = -1; + e_devicemgr.gamepad_id = -1; + e_devicemgr.gesture_id = -1; + e_devicemgr.virtual_multitouch_done = 1; + e_devicemgr.device_list = NULL; + e_devicemgr.palm_disabled = EINA_FALSE; + e_devicemgr.atomDeviceEnabled = ecore_x_atom_get(XI_PROP_DEVICE_ENABLE); + e_devicemgr.atomRROutput = ecore_x_atom_get(E_PROP_XRROUTPUT); + e_devicemgr.atomDeviceName = ecore_x_atom_get(E_PROP_DEVICE_NAME); + e_devicemgr.atomDeviceList = ecore_x_atom_get(E_PROP_DEVICE_LIST); + e_devicemgr.atomXMouseExist = ecore_x_atom_get(E_PROP_X_MOUSE_EXIST); + e_devicemgr.atomXMouseCursorEnable = ecore_x_atom_get(E_PROP_X_MOUSE_CURSOR_ENABLE); + e_devicemgr.atomXExtKeyboardExist = ecore_x_atom_get(E_PROP_X_EXT_KEYBOARD_EXIST); + e_devicemgr.atomHWKbdInputStarted = ecore_x_atom_get(E_PROP_HW_KEY_INPUT_STARTED); + e_devicemgr.atomAxisLabels = ecore_x_atom_get(E_PROP_X_EVDEV_AXIS_LABELS); + e_devicemgr.atomButtonLabels = ecore_x_atom_get(E_PROP_X_EVDEV_BUTTON_LABELS); + e_devicemgr.atomVirtualTouchpadConfineRegion = ecore_x_atom_get(E_PROP_VIRTUAL_TOUCHPAD_CONFINE_REGION); + e_devicemgr.atomVirtualTouchpad = ecore_x_atom_get(E_PROP_VIRTUAL_TOUCHPAD); + e_devicemgr.atomVirtualTouchpadInt = ecore_x_atom_get(E_PROP_VIRTUAL_TOUCHPAD_INT); + e_devicemgr.atomDeviceMgrInputWindow = ecore_x_atom_get(E_PROP_DEVICEMGR_INPUTWIN); + e_devicemgr.atomTouchInput = ecore_x_atom_get(E_PROP_TOUCH_INPUT); + e_devicemgr.atomScrnConfDispModeSet = ecore_x_atom_get(STR_ATOM_SCRNCONF_DISPMODE_SET); + e_devicemgr.atomVirtMonReq = ecore_x_atom_get(STR_ATOM_VIRT_MONITOR_REQUEST); + e_devicemgr.atomHibReq = ecore_x_atom_get(STR_ATOM_HIB_REQUEST); + e_devicemgr.atomDevMgrCfg = ecore_x_atom_get(STR_ATOM_DEVICEMGR_CFG); + e_devicemgr.atomFloat = ecore_x_atom_get(XATOM_FLOAT); + e_devicemgr.atomInputTransform = ecore_x_atom_get(EVDEVMULTITOUCH_PROP_TRANSFORM); + e_devicemgr.atomExKeyboardEnabled = ecore_x_atom_get(E_PROP_EXTERNAL_KEYBOARD_ENABLED); + e_devicemgr.atomRelativeMoveStatus = ecore_x_atom_get(XI_PROP_REL_MOVE_STATUS); + e_devicemgr.atomRelativeMoveAck = ecore_x_atom_get(XI_PROP_REL_MOVE_ACK); + e_devicemgr.atomGameModeEnabled = ecore_x_atom_get(E_PROP_GAMEMODE_ENABLED); + e_devicemgr.atomMultitouchDeviceId = ecore_x_atom_get(E_PROP_MULTITOUCH_DEVICEID); + + e_devicemgr.atomPalmDisablingWinRunning = ecore_x_atom_get(E_PROP_PALM_DISABLING_WIN_RUNNING); + e_devicemgr.palmDisablingWin = -1; + + e_devicemgr.atomPalmRejectionMode = ecore_x_atom_get(GESTURE_PALM_REJECTION_MODE); + + e_devicemgr.atomWindowStackisChanged = ecore_x_atom_get(GESTURE_WINDOW_STACK_CHANGED); + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] e_devicemgr.atomRelativeMoveStatus = %d\n", e_devicemgr.atomRelativeMoveStatus); + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] e_devicemgr.atomRelativeMoveAck = %d\n", e_devicemgr.atomRelativeMoveAck); + + memset(&e_devicemgr.virtual_touchpad_area_info, -1, sizeof(e_devicemgr.virtual_touchpad_area_info)); + memset(&e_devicemgr.virtual_multitouch_id, -1, sizeof(e_devicemgr.virtual_multitouch_id)); + e_devicemgr.virtual_touchpad_pointed_window = 0; + e_devicemgr.zones = NULL; + + e_devicemgr.input_window = ecore_x_window_input_new(e_devicemgr.rootWin, -1, -1, 1, 1); + + if (!e_devicemgr.input_window) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to create input_window !\n"); + ret = 0; + goto out; + } + else + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Succeed to create input_window (0x%x)!\n", e_devicemgr.input_window); + ecore_x_window_prop_property_set(e_devicemgr.rootWin, e_devicemgr.atomDeviceMgrInputWindow, ECORE_X_ATOM_WINDOW, 32, &e_devicemgr.input_window, 1); + } + + ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomTouchInput, &val, 1); + ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomExKeyboardEnabled, &enable, 1); + ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomGameModeEnabled, &disable, 1); + ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomPalmDisablingWinRunning, &no_window, 1); + + res = _e_devicemgr_xinput_init(); + if (!res) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to initialize XInput Extension !\n"); + ret =0; + goto out; + } + + res = _e_devicemgr_xkb_init(); + if (!res) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to initialize XKB Extension !\n"); + ret = 0; + goto out; + } + + e_mod_scrnconf_external_init(); + + _e_devicemgr_init_transform_matrix(); + _e_devicemgr_init_input(); + _e_devicemgr_init_output(); + + res = _e_devicemgr_get_configuration(); + if (!res) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to get configuration from %s.cfg file !\n", E_DEVICEMGR_CFG); + ret =0; + goto out; + } + + e_mod_scrnconf_container_bg_canvas_visible_set(EINA_FALSE); + if(EINA_FALSE == e_mod_sf_rotation_init()) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to init rotation!\n"); + } + +out: + return ret; +} + +static void +_e_devicemgr_fini(void) +{ + if(EINA_FALSE == e_mod_sf_rotation_deinit()) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Failed to deinit rotation!\n"); + } + + e_mod_devicemgr_config_shutdown(); +} + + +static void +_get_preferred_size (int sc_output, int *preferred_w, int *preferred_h) +{ + if (sc_output == SC_EXT_OUTPUT_HDMI) + { + *preferred_w = e_devicemgr.hdmi_preferred_w; + *preferred_h = e_devicemgr.hdmi_preferred_h; + } + else if (sc_output == SC_EXT_OUTPUT_VIRTUAL) + { + *preferred_w = e_devicemgr.virtual_preferred_w; + *preferred_h = e_devicemgr.virtual_preferred_h; + } + else + { + *preferred_w = 0; + *preferred_h = 0; + } +} + +static void +_e_devicemgr_selection_atom_init (void) +{ + static Eina_Bool init = EINA_FALSE; + + if (init) return; + init = EINA_TRUE; + + if (!e_devicemgr.selection_atom) + e_devicemgr.selection_atom = ecore_x_atom_get ("SEL_EXT_DISPLAY"); + if( !e_devicemgr.selection_type_atom) + e_devicemgr.selection_type_atom = ecore_x_atom_get ("SEL_EXT_DISPLAY_TYPE"); +} + +static void +_e_devicemgr_selection_dialog_new (char *owner) +{ + Ecore_Exe *exe; + char cmd[4096]; + + E_MOD_SCRNCONF_CHK (owner != NULL); + + /* external_dialog_name, icccm_name, icccm_class, popup_title, popup_contents */ + snprintf (cmd, sizeof (cmd), "/usr/bin/extndialog HDMI-CONVERGENCE HDMI-CONVERGENCE %s", owner); + exe = ecore_exe_run (cmd, NULL); + + SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] Do '%s'. exe(%p)\n", cmd, exe); + + if (exe) + ecore_exe_free (exe); +} + +static char* +_e_devicemgr_selection_get_owner (void) +{ + Ecore_X_Window xwin; + + _e_devicemgr_selection_atom_init (); + + xwin = ecore_x_selection_owner_get (e_devicemgr.selection_atom); + if (!xwin) + return NULL; + + return ecore_x_window_prop_string_get (xwin, e_devicemgr.selection_type_atom); +} + +static void +_e_devicemgr_selection_ensure_xwindow (void) +{ + if (e_devicemgr.selection_xwin > 0) + return; + + e_devicemgr.selection_xwin = ecore_x_window_new ((Ecore_X_Window)NULL, -100, -100, 10, 10); + E_MOD_SCRNCONF_CHK (e_devicemgr.selection_xwin != 0); + XStoreName (ecore_x_display_get (), e_devicemgr.selection_xwin, "DEVMGR-HDMI-SELECTION"); + ecore_x_window_override_set (e_devicemgr.selection_xwin, EINA_TRUE); + ecore_x_window_show (e_devicemgr.selection_xwin); +} + +static Eina_Bool +_e_devicemgr_selection_request_timeout (void *data) +{ + SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] xselection timeout(%d)\n", + (int)XSELECTION_TIMEOUT); + + _e_devicemgr_selection_notify_cb (NULL, 0, NULL); + + return ECORE_CALLBACK_CANCEL; +} + +static void +_e_devicemgr_selection_request (void) +{ + _e_devicemgr_selection_atom_init (); + _e_devicemgr_selection_ensure_xwindow (); + + SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] request that '%s' releases xselection ownership.\n", e_devicemgr.selection_prev_owner); + + /* handler for xselection */ + e_devicemgr.selection_notify_handler = ecore_event_handler_add (ECORE_X_EVENT_SELECTION_NOTIFY, + _e_devicemgr_selection_notify_cb, NULL); + e_devicemgr.selection_request_timeout = ecore_timer_add (XSELECTION_TIMEOUT, + _e_devicemgr_selection_request_timeout, NULL); + + XConvertSelection (ecore_x_display_get (), + e_devicemgr.selection_atom, + e_devicemgr.selection_type_atom, + e_devicemgr.selection_type_atom, + e_devicemgr.selection_xwin, 0); +} + +static Eina_Bool +_e_devicemgr_selection_set (void) +{ + if (e_devicemgr.selection_ownership) + { + SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] already has xselection ownership.\n"); + return EINA_TRUE; + } + + _e_devicemgr_selection_atom_init (); + _e_devicemgr_selection_ensure_xwindow (); + + /* The previous owner receives a "SelectionClear" event. */ + ecore_x_selection_owner_set (e_devicemgr.selection_xwin, e_devicemgr.selection_atom, 0); + if (e_devicemgr.selection_xwin != ecore_x_selection_owner_get (e_devicemgr.selection_atom)) + { + SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] failed to take xselection ownership.\n"); + return EINA_FALSE; + } + + e_devicemgr.selection_clear_handler = ecore_event_handler_add (ECORE_X_EVENT_SELECTION_CLEAR, + _e_devicemgr_selection_clear_cb, NULL); + e_devicemgr.selection_request_handler = ecore_event_handler_add (ECORE_X_EVENT_SELECTION_REQUEST, + _e_devicemgr_selection_request_cb, NULL); + + ecore_x_window_prop_string_set (e_devicemgr.selection_xwin, e_devicemgr.selection_type_atom, XSELECTION_HDMI_NAME); + SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] set xselection ownership. xwin(%x)\n", e_devicemgr.selection_xwin); + + e_devicemgr.selection_ownership = EINA_TRUE; + + return EINA_TRUE; +} + +static Eina_Bool +_e_devicemgr_selection_clear (void) +{ + _e_devicemgr_selection_atom_init (); + + e_devicemgr.selection_ownership = EINA_FALSE; + + if (e_devicemgr.selection_xwin) + { + ecore_x_window_free (e_devicemgr.selection_xwin); + e_devicemgr.selection_xwin = 0; + } + + e_devicemgr.selection_output_xid = 0; + memset (e_devicemgr.selection_prev_owner, 0, sizeof (e_devicemgr.selection_prev_owner)); + + if (e_devicemgr.selection_clear_handler) + { + ecore_event_handler_del (e_devicemgr.selection_clear_handler); + e_devicemgr.selection_clear_handler = NULL; + } + if (e_devicemgr.selection_request_handler) + { + ecore_event_handler_del (e_devicemgr.selection_request_handler); + e_devicemgr.selection_request_handler = NULL; + } + if (e_devicemgr.selection_notify_handler) + { + ecore_event_handler_del (e_devicemgr.selection_notify_handler); + e_devicemgr.selection_notify_handler = NULL; + } + if (e_devicemgr.selection_request_timeout) + { + ecore_timer_del (e_devicemgr.selection_request_timeout); + e_devicemgr.selection_request_timeout = NULL; + } + + SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] clear xselection\n"); + + return EINA_TRUE; +} + +static Eina_Bool +_e_devicemgr_selection_clear_cb (void* data, int type, void *event) +{ + SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] xselection ownership gone.\n"); + + if (e_devicemgr.selection_ownership) + _e_devicemgr_disconnect (e_devicemgr.selection_output_xid); + + return EINA_FALSE; +} + +static Eina_Bool +_e_devicemgr_selection_request_cb (void* data, int type, void *event) +{ + Ecore_X_Event_Selection_Request *e = (Ecore_X_Event_Selection_Request*)event; + + SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] someone wants to take ownership.\n"); + + _e_devicemgr_disconnect (e_devicemgr.selection_output_xid); + + /* send notify for other application to allow to take ownership */ + ecore_x_selection_notify_send (e->requestor, e->selection, e->target, + e->property, 0); + + return EINA_FALSE; +} + +static Eina_Bool +_e_devicemgr_selection_notify_cb (void* data, int type, void *event) +{ + SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] ready to take ownership.\n"); + + if (e_devicemgr.selection_request_timeout) + { + ecore_timer_del (e_devicemgr.selection_request_timeout); + e_devicemgr.selection_request_timeout = NULL; + } + if (e_devicemgr.selection_notify_handler) + { + ecore_event_handler_del (e_devicemgr.selection_notify_handler); + e_devicemgr.selection_notify_handler = NULL; + } + + if(!_e_devicemgr_selection_set ()) + return EINA_FALSE; + + _e_devicemgr_selection_dialog_new (e_devicemgr.selection_prev_owner); + _e_devicemgr_dialog_and_connect (e_devicemgr.selection_output_xid); + + return EINA_FALSE; +} + +static Eina_Bool +_e_devicemgr_dialog_and_connect (Ecore_X_Randr_Output output_xid) +{ + int preferred_w =0, preferred_h = 0; + int sc_output = 0; + int sc_res = 0; + + /* set the output of the external monitor */ + sc_output = e_mod_scrnconf_external_get_output_from_xid (output_xid); + E_MOD_SCRNCONF_CHK_RET (sc_output != SC_EXT_OUTPUT_NULL, EINA_TRUE); + + e_mod_scrnconf_external_set_output (sc_output); + + /* set the resolution of the external monitor */ + _get_preferred_size (sc_output, &preferred_w, &preferred_h); + sc_res = e_mod_scrnconf_external_get_default_res (sc_output, preferred_w, preferred_h); + E_MOD_SCRNCONF_CHK_GOTO (sc_res != SC_EXT_RES_NULL, fail); + e_mod_scrnconf_external_set_res (sc_res); + + /* set the default display mode of the external monitor */ + if (e_devicemgr.default_dispmode == UTILX_SCRNCONF_DISPMODE_CLONE || + e_devicemgr.default_dispmode == UTILX_SCRNCONF_DISPMODE_EXTENDED) + { + + if (!e_mod_scrnconf_external_set_dispmode (sc_output, e_devicemgr.default_dispmode, sc_res)) + { + e_mod_scrnconf_external_set_status (UTILX_SCRNCONF_STATUS_CONNECT); + /* generate dialog */ + if (e_devicemgr.isPopUpEnabled) + e_mod_scrnconf_external_dialog_new (sc_output); + goto fail; + } + + e_mod_scrnconf_external_set_status (UTILX_SCRNCONF_STATUS_ACTIVE); + } + else + { + e_mod_scrnconf_external_set_status (UTILX_SCRNCONF_STATUS_CONNECT); + } + + /* generate dialog */ + if (e_devicemgr.isPopUpEnabled) + e_mod_scrnconf_external_dialog_new (sc_output); + + e_mod_scrnconf_external_send_current_status(); + + return EINA_TRUE; + +fail: + e_mod_scrnconf_external_reset (sc_output); + return EINA_TRUE; +} + +static Eina_Bool +_e_devicemgr_disconnect (Ecore_X_Randr_Output output_xid) +{ + int sc_output = 0; + + /* if display mode is set by the client message, ignore output disconnected */ + if (e_mod_set_disp_clone) + return EINA_TRUE; + + _e_devicemgr_selection_clear (); + + /* set the output of the external monitor */ + sc_output = e_mod_scrnconf_external_get_output_from_xid (output_xid); + E_MOD_SCRNCONF_CHK_RET (sc_output != SC_EXT_OUTPUT_NULL, 1); + + e_mod_scrnconf_external_reset (sc_output); + + e_mod_scrnconf_external_send_current_status(); + + /* if dialog is still showing, destroy dialog */ + e_mod_scrnconf_external_dialog_free(); + + e_mod_scrnconf_container_bg_canvas_visible_set(EINA_FALSE); + + return EINA_TRUE; +} + +static int +_e_devicemgr_cb_crtc_change (void *data, int type, void *ev) +{ + if (type == ECORE_X_EVENT_RANDR_CRTC_CHANGE) + { + //SLOG(LOG_DEBUG, "DEVICEMGR", "[scrn-conf]: Crtc Change!: \n"); + //Ecore_X_Event_Randr_Crtc_Change *event = (Ecore_X_Event_Randr_Crtc_Change *)ev; + /* available information: + struct _Ecore_X_Event_Randr_Crtc_Change + { + Ecore_X_Window win; + Ecore_X_Randr_Crtc crtc; + Ecore_X_Randr_Mode mode; + Ecore_X_Randr_Orientation orientation; + int x; + int y; + int width; + int height; + }; + */ + } + + return EINA_TRUE; +} + +static int +_e_devicemgr_cb_output_change (void *data, int type, void *ev) +{ + int sc_stat = 0; + + if (type == ECORE_X_EVENT_RANDR_OUTPUT_CHANGE) + { + //SLOG(LOG_DEBUG, "DEVICEMGR", "[scrn-conf]: Output Change!: \n"); + Ecore_X_Event_Randr_Output_Change *event = (Ecore_X_Event_Randr_Output_Change *)ev; + /* available information: + struct _Ecore_X_Event_Randr_Output_Change + { + Ecore_X_Window win; + Ecore_X_Randr_Output output; + Ecore_X_Randr_Crtc crtc; + Ecore_X_Randr_Mode mode; + Ecore_X_Randr_Orientation orientation; + Ecore_X_Randr_Connection_Status connection; + Ecore_X_Render_Subpixel_Order subpixel_order; + }; + */ + + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: event (crtc:%d, output:%d, mode:%d)\n", + event->crtc, event->output, event->mode); + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: Output Connection!: %d (connected = %d, disconnected = %d, unknown %d)\n", + event->connection, ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED, ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED, ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN); + + /* check status of a output */ + if (event->connection == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED && + event->crtc == 0 && + event->mode == 0) + { + /* if display mode is set by the client message, ignore output conncetion */ + if (e_mod_set_disp_clone) + { + /* reset flag to default */ + e_mod_set_disp_clone = EINA_FALSE; + return EINA_TRUE; + } + + sc_stat = e_mod_scrnconf_external_get_status(); + if (sc_stat == UTILX_SCRNCONF_STATUS_CONNECT || + sc_stat == UTILX_SCRNCONF_STATUS_ACTIVE) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : external monitor status is already connected \n"); + return 1; + } + + /* if don't have xselection's ownership, ignore output disconnected */ + if (e_devicemgr.selection_ownership) + SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] connected twice.\n"); + + char *prev_owner = _e_devicemgr_selection_get_owner (); + + e_devicemgr.selection_output_xid = event->output; + + SLOG (LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] selection owner : '%s'.\n", + (prev_owner)?prev_owner:"none"); + + if (!prev_owner) + _e_devicemgr_selection_set (); + else + { + snprintf (e_devicemgr.selection_prev_owner, sizeof (e_devicemgr.selection_prev_owner), + "%s", prev_owner); + + if (strcmp (prev_owner, XSELECTION_HDMI_NAME)) + { + _e_devicemgr_selection_request (); + free (prev_owner); + return EINA_FALSE; + } + free (prev_owner); + } + + _e_devicemgr_dialog_and_connect (event->output); + } + else if (event->connection == ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED) + { + _e_devicemgr_disconnect (event->output); + } + else if (event->connection == ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN) + { + /* if dialog is still showing, destroy dialog */ + e_mod_scrnconf_external_dialog_free(); + + if (e_devicemgr.default_dispmode == UTILX_SCRNCONF_DISPMODE_EXTENDED) + { + e_mod_scrnconf_container_bg_canvas_visible_set(EINA_TRUE); + } + } + + } + + return EINA_TRUE; +} + +static int +_e_devicemgr_cb_output_property (void *data, int type, void *ev) +{ + if (type == ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY) + { + //SLOG(LOG_DEBUG, "DEVICEMGR", "[scrn-conf]: Output Property Notify!: \n"); + //Ecore_X_Event_Randr_Output_Property_Notify *event = (Ecore_X_Event_Randr_Output_Property_Notify *)ev; + /* available information: + struct _Ecore_X_Event_Randr_Output_Property_Notify + { + Ecore_X_Window win; + Ecore_X_Randr_Output output; + Ecore_X_Atom property; + Ecore_X_Time time; + Ecore_X_Randr_Property_Change state; + }; + */ + } + + return EINA_TRUE; +} + +static int +_e_devicemgr_cb_client_message (void* data, int type, void* event) +{ + Ecore_X_Event_Client_Message* ev = event; + int req = 0; + int sc_dispmode = 0; + int sc_res = 0; + int sc_stat = 0; + int sc_output = 0; + int preferred_w = 0, preferred_h = 0; + int pos[2]; + int cx, cy; + int x1, y1, x2, y2; + int w, h, px = 0, py = 0; + int vw, vh, pw = 0, ph = 0; + int region[5]; + int pos_rootx, pos_rooty; + + if (ev->message_type == e_devicemgr.atomVirtualTouchpadInt) + { + if (e_devicemgr.num_zones < 2) + { + ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt, + ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_SHUTDOWN, 0, 0, 0, 0); + return 1; + } + + if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_NEED_TO_INIT) + { + ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt, + ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_DO_INIT, 0, 0, 0, 0); + } + else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_AREA_INFO) + { + e_devicemgr.virtual_touchpad_area_info[0] = ev->data.l[1]; + e_devicemgr.virtual_touchpad_area_info[1] = ev->data.l[2]; + e_devicemgr.virtual_touchpad_area_info[2] = ev->data.l[3]; + e_devicemgr.virtual_touchpad_area_info[3] = ev->data.l[4]; + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] virtual_touchpad_area_info=%d %d %d %d\n", + e_devicemgr.virtual_touchpad_area_info[0], e_devicemgr.virtual_touchpad_area_info[1], + e_devicemgr.virtual_touchpad_area_info[2], e_devicemgr.virtual_touchpad_area_info[3]); + } + else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_WINDOW) + { + e_devicemgr.virtual_touchpad_window = (Ecore_X_Window)ev->data.l[1]; + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] virtual_touchpad_window=0x%x\n", e_devicemgr.virtual_touchpad_window); + } + else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_CONFINE_SET) + { + _e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, _e_devicemgr_get_nth_zone(2), EINA_TRUE, NULL, EINA_FALSE, EINA_TRUE); + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] E_VIRTUAL_TOUCHPAD_CONFINE_SET\n"); + } + else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_CONFINE_UNSET) + { + _e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, NULL, EINA_FALSE, NULL, EINA_FALSE, EINA_FALSE); + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] E_VIRTUAL_TOUCHPAD_CONFINE_UNSET\n"); + } + else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_MT_BEGIN) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] E_VIRTUAL_TOUCHPAD_MT_BEGIN !virtual_multitouch_done=%d\n", e_devicemgr.virtual_multitouch_done); + + if (0 != e_devicemgr.virtual_touchpad_pointed_window) + { + XISetClientPointer(e_devicemgr.disp, e_devicemgr.virtual_touchpad_pointed_window, e_devicemgr.virtual_touchpad_id); + XSync(e_devicemgr.disp, 0); + ecore_x_pointer_xy_get(e_devicemgr.virtual_touchpad_pointed_window, &pos[0], &pos[1]); + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][_cb_client_message] cursor pos x=%d, y=%d\n", pos[0], pos[1]); + + if (pos[0] < 0 || pos[1] < 0 ) return 1; + + e_devicemgr.virtual_multitouch_done = 0; + + x1 = e_devicemgr.virtual_touchpad_pointed_window_info[0]; + y1 = e_devicemgr.virtual_touchpad_pointed_window_info[1]; + w = e_devicemgr.virtual_touchpad_pointed_window_info[2]; + h = e_devicemgr.virtual_touchpad_pointed_window_info[3]; + + x2 = x1+w; + y2 = y1+h; + cx = x1 + pos[0]; + cy = y1 + pos[1]; + + if (INSIDE(cx, cy, x1, y1, x1+(w/2), y1+(h/2))) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 1st box (x1=%d, y1=%d, x2=%d, y2=%d)!\n", x1, y1, x1+(w/2), y1+(h/2)); + pw = pos[0]*2; + ph = pos[1]*2; + px = x1; + py = y1; + SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 1st box (effective area = %d, %d, %d, %d)!\n", px, py, pw, ph); + } + else if (INSIDE(cx, cy, x1+(w/2), y1, x2, y1+(h/2))) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 2nd box (x1=%d, y1=%d, x2=%d, y2=%d)!\n", x1+(w/2), y1, x2, y1+(h/2)); + pw = (w-pos[0])*2; + ph = pos[1]*2; + px = x2-pw; + py = y1; + SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 2nd box (effective area = %d, %d, %d, %d)!\n", px, py, pw, ph); + } + else if (INSIDE(cx, cy, x1, y1+(h/2), x1+(w/2), y2)) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 3rd box (x1=%d, y1=%d, x2=%d, y2=%d)!\n", x1, y1+(h/2), x1+(w/2), y2); + pw = pos[0]*2; + ph = (h-pos[1])*2; + px = x1; + py = y2-ph; + SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 3rd box (effective area = %d, %d, %d, %d)!\n", px, py, pw, ph); + } + else if (INSIDE(cx, cy, x1+(w/2), y1+(h/2), x2, y2)) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 4th box (x1=%d, y1=%d, x2=%d, y2=%d)!\n", x1+(w/2), y1+(h/2), x2, y2); + pw = (w-pos[0])*2; + ph = (h-pos[1])*2; + px = x2-pw; + py = y2-ph; + SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] 4th box (effective area = %d, %d, %d, %d)!\n", px, py, pw, ph); + } + else + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[_client_message] !!! pointer is not in 4 boxes !!!\n"); + } + + vw = e_devicemgr.virtual_touchpad_area_info[2] -e_devicemgr.virtual_touchpad_area_info[0]; + vh = e_devicemgr.virtual_touchpad_area_info[3] -e_devicemgr.virtual_touchpad_area_info[1]; + + if ((pw) && (vw > pw)) e_devicemgr.tmatrix[0] = (float)vw/pw; + else if (vw) e_devicemgr.tmatrix[0] = (float)pw/vw; + if ((ph) && (vh > ph)) e_devicemgr.tmatrix[4] = (float)vh/ph; + else if (vh) e_devicemgr.tmatrix[4] = (float)ph/vh; + + e_devicemgr.virtual_touchpad_cursor_pos[0] = pos[0]; + e_devicemgr.virtual_touchpad_cursor_pos[1] = pos[1]; + e_devicemgr.tmatrix[2] = (float)px*e_devicemgr.tmatrix[0]*(-1); + e_devicemgr.tmatrix[5] = (float)py*e_devicemgr.tmatrix[4]*(-1); + _e_devicemgr_update_input_transform_matrix(EINA_FALSE); + + region[0] = e_devicemgr.virtual_touchpad_pointed_window_info[0] + 10; + region[1] = e_devicemgr.virtual_touchpad_pointed_window_info[1] + 10; + region[2] = e_devicemgr.virtual_touchpad_pointed_window_info[2] - 20; + region[3] = e_devicemgr.virtual_touchpad_pointed_window_info[3] - 20; + region[4] = 0; + _e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, NULL, EINA_TRUE, ®ion[0], EINA_FALSE, EINA_TRUE); + ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt, + ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_MT_MATRIX_SET_DONE, 0, 0, 0, 0); + } + } + else if (ev->data.l[0] == E_VIRTUAL_TOUCHPAD_MT_END) + { + e_devicemgr.virtual_multitouch_done = 1; + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_client_message] E_VIRTUAL_TOUCHPAD_MT_END !virtual_multitouch_done=%d\n", e_devicemgr.virtual_multitouch_done); + if (0 != e_devicemgr.virtual_touchpad_pointed_window) + { + _e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, NULL, EINA_FALSE, NULL, EINA_FALSE, EINA_FALSE); + //_e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, _e_devicemgr_get_nth_zone(2), EINA_TRUE, NULL, EINA_FALSE); + if (e_devicemgr.virtual_touchpad_cursor_pos[0] >= 0 && e_devicemgr.virtual_touchpad_cursor_pos[1] >= 0) + { + pos_rootx = e_devicemgr.virtual_touchpad_cursor_pos[0] + e_devicemgr.virtual_touchpad_pointed_window_info[0]; + pos_rooty = e_devicemgr.virtual_touchpad_cursor_pos[1] + e_devicemgr.virtual_touchpad_pointed_window_info[1]; + ecore_x_pointer_warp(e_devicemgr.virtual_touchpad_pointed_window, e_devicemgr.virtual_touchpad_cursor_pos[0], e_devicemgr.virtual_touchpad_cursor_pos[1]); + e_devicemgr.virtual_touchpad_cursor_pos[0] = -1; + e_devicemgr.virtual_touchpad_cursor_pos[1] = -1; + } + } + } + + return 1; + } + + if (ev->message_type == e_devicemgr.atomScrnConfDispModeSet) + { + sc_dispmode = (int)ev->data.s[0]; + + sc_stat = e_mod_scrnconf_external_get_status(); + if (sc_stat == UTILX_SCRNCONF_STATUS_NULL) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : external monitor is not connected \n"); + return 1; + } + + if (sc_dispmode == e_mod_scrnconf_external_get_dispmode()) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : the same dispmode is already set \n"); + return 1; + } + + sc_output = e_mod_scrnconf_external_get_output(); + E_MOD_SCRNCONF_CHK_RET(sc_output != SC_EXT_OUTPUT_NULL, 1); + + _get_preferred_size (sc_output, &preferred_w, &preferred_h); + sc_res = e_mod_scrnconf_external_get_default_res (sc_output, preferred_w, preferred_h); + E_MOD_SCRNCONF_CHK_RET(sc_res != SC_EXT_RES_NULL, 1); + + if (!e_mod_scrnconf_external_set_dispmode (sc_output, sc_dispmode, sc_res)) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to get external output \n"); + return 1; + } + + e_mod_scrnconf_external_set_status (UTILX_SCRNCONF_STATUS_ACTIVE); + e_mod_scrnconf_external_send_current_status(); + + /* if disp_mode is set by the client message, set clone flag for preventing + the output disconnect/connect */ + if (sc_dispmode == UTILX_SCRNCONF_DISPMODE_CLONE) + e_mod_set_disp_clone = EINA_TRUE; + } + else if (ev->message_type == e_devicemgr.atomVirtMonReq) + { + req = (int)ev->data.s[0]; + e_devicemgr.virtual_preferred_w = (int)ev->data.s[1]; + e_devicemgr.virtual_preferred_h = (int)ev->data.s[2]; + + /* deal with edid data */ + e_mod_drv_virt_mon_set (req); + } + else if (ev->message_type == e_devicemgr.atomHibReq) + { + req = (int)ev->data.s[0]; + } + else if (ev->message_type == e_devicemgr.atomDevMgrCfg) + { + Eina_Bool set_popup = EINA_FALSE; + req = (int)ev->data.s[0]; + if (req == DEVICEMGR_CFG_POPUP) + { + set_popup = (Eina_Bool)ev->data.s[1]; + e_devicemgr.isPopUpEnabled = set_popup; + _e_devicemgr_cfg->ScrnConf.isPopUpEnabled = set_popup; + } + else if (req == DEVICEMGR_CFG_DEFAULT_DISPMODE) + { + sc_dispmode = (int)ev->data.s[1]; + e_devicemgr.default_dispmode = sc_dispmode; + _e_devicemgr_cfg->ScrnConf.default_dispmode = sc_dispmode; + } + else + { + return 1; + } + + /* update deivcemgr configuration */ + _e_devicemgr_update_configuration(); + } + else + { + ; + } + + return 1; +} + +static void +_e_mod_move_e_msg_handler(void *data, const char *name, const char *info, int val, E_Object *obj, void *msgdata) +{ + Eina_List* l; + DeviceMgr_Device_Info *ldata; + unsigned int ret_val = 1; + + if (!strncmp(name, "e.move.quickpanel", sizeof("e.move.quickpanel"))) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] e.move.quickpanel is comming (%s): val: %d\n", info, val); + if ((!strncmp(info, "start", sizeof("start")))) + { + // quickpanel state on + ret_val = 0; + ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomExKeyboardEnabled, &ret_val, 1); + EINA_LIST_FOREACH(e_devicemgr.device_list, l ,ldata) + { + if(ldata->type == E_DEVICEMGR_KEYBOARD || ldata->type == E_DEVICEMGR_GAMEPAD) + { + if(_e_devicemgr_detach_slave(ldata->id) == EINA_FALSE) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to detach slave device(%d) \n", ldata->id); + } + } + } + } + else if ((!strncmp(info, "end", sizeof("end"))) && (val == 0)) + { + // quickpanel state off + ret_val = 1; + ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomExKeyboardEnabled, &ret_val, 1); + EINA_LIST_FOREACH(e_devicemgr.device_list, l ,ldata) + { + if(ldata->type == E_DEVICEMGR_KEYBOARD || ldata->type == E_DEVICEMGR_GAMEPAD) + { + if(_e_devicemgr_reattach_slave(ldata->id, ldata->master_id) == EINA_FALSE) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to reattach slave device(%d) to master device(%d) \n", ldata->id, e_devicemgr.vck_id); + } + } + } + } + } +} + +static int +_e_devicemgr_xinput_init(void) +{ + int event, error; + int major = 2, minor = 0; + + if (!XQueryExtension(e_devicemgr.disp, "XInputExtension", &e_devicemgr.xi2_opcode, &event, &error)) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] XInput Extension isn't supported.\n", __FUNCTION__); + goto fail; + } + + if (XIQueryVersion(e_devicemgr.disp, &major, &minor) == BadRequest) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to query XI version.\n", __FUNCTION__); + goto fail; + } + + memset(&e_devicemgr.eventmask, 0L, sizeof(XIEventMask)); + e_devicemgr.eventmask.deviceid = XIAllDevices; + e_devicemgr.eventmask.mask_len = XIMaskLen(XI_RawMotion); + e_devicemgr.eventmask.mask = calloc(e_devicemgr.eventmask.mask_len, sizeof(char)); + + /* Events we want to listen for all */ + XISetMask(e_devicemgr.eventmask.mask, XI_DeviceChanged); + XISetMask(e_devicemgr.eventmask.mask, XI_HierarchyChanged); + XISetMask(e_devicemgr.eventmask.mask, XI_PropertyEvent); + XISelectEvents(e_devicemgr.disp, e_devicemgr.rootWin, &e_devicemgr.eventmask, 1); + + return 1; + +fail: + e_devicemgr.xi2_opcode = -1; + return 0; +} + +static int +_e_devicemgr_xkb_init(void) +{ + int xkb_opcode, xkb_event, xkb_error; + int xkb_lmaj = XkbMajorVersion; + int xkb_lmin = XkbMinorVersion; + + if (!(XkbLibraryVersion(&xkb_lmaj, &xkb_lmin) + && XkbQueryExtension(e_devicemgr.disp, &xkb_opcode, &xkb_event, &xkb_error, &xkb_lmaj, &xkb_lmin))) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][xkb_init] Failed to initialize XKB extension !\n"); + e_devicemgr.xkb_available = EINA_FALSE; + return 0; + } + + e_devicemgr.xkb_available = EINA_TRUE; + return 1; +} + +static int +_e_devicemgr_cb_window_property(void *data, int ev_type, void *ev) +{ + int res; + unsigned int ret_val = 0; + Ecore_X_Event_Window_Property *e = ev; + + int enable=1; + int disable=0; + + if (e->atom == e_devicemgr.atomDeviceList && e->win == e_devicemgr.input_window) + { + res = ecore_x_window_prop_card32_get(e->win, e_devicemgr.atomDeviceList, &ret_val, 1); + + if (res == 1) _e_devicemgr_show_device_list(ret_val); + goto out; + } + + if (e->atom == e_devicemgr.atomVirtualTouchpad && e->win == e_devicemgr.input_window) + { + res = ecore_x_window_prop_card32_get(e->win, e_devicemgr.atomVirtualTouchpad, &ret_val, 1); + + if (res == 1 && e_devicemgr.virtual_touchpad_id > 0) + { + ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt, + ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_SHUTDOWN, 0, 0, 0, 0); + } + goto out; + } + if (e->atom == e_devicemgr.atomGameModeEnabled && e->win == e_devicemgr.input_window) + { + res = ecore_x_window_prop_card32_get(e->win, e_devicemgr.atomGameModeEnabled, &ret_val, 1); + + if (res == 1) + { + /* "Game Mode Enable" means that gamepad input shall uniquely go to gamepad-using game app WITHOUT X server, + therefore DISABLING the gamepad (for X server), + and vice versa -- "Game Mode Disable" means "gamepad ENABLE".*/ + if (ret_val == 1) + { + XIChangeProperty(e_devicemgr.disp, e_devicemgr.gamepad_id, e_devicemgr.atomDeviceEnabled, + XA_INTEGER, 8, PropModeReplace, &disable, 1); + } + else + { + XIChangeProperty(e_devicemgr.disp, e_devicemgr.gamepad_id, e_devicemgr.atomDeviceEnabled, + XA_INTEGER, 8, PropModeReplace, &enable, 1); + } + } + goto out; + } + if (e->atom == e_devicemgr.atomPalmDisablingWinRunning && e->win == e_devicemgr.input_window) + { + + Ecore_X_Window highlight_win; + res = ecore_x_window_prop_card32_get(e->win, e_devicemgr.atomPalmDisablingWinRunning, &ret_val, 1); + if (res <=0) + goto out; + + SLOG(LOG_DEBUG, "DEVICEMGR", "E_PROP_PALM_DISABLING_WIN_RUNNING (0x%x -> 0x%x)\n", e_devicemgr.palmDisablingWin, ret_val); + + e_devicemgr.palmDisablingWin = ret_val; + + res = ecore_x_window_prop_window_get(e_devicemgr.rootWin, ECORE_X_ATOM_NET_ACTIVE_WINDOW, &highlight_win, 1); + if (res <=0) + goto out; + + SLOG(LOG_DEBUG, "DEVICEMGR", "highlight_win: 0x%x)\n", highlight_win); + + if (e_devicemgr.palmDisablingWin == highlight_win) + { + e_devicemgr.palm_disabled = EINA_TRUE; + XIChangeProperty(e_devicemgr.disp, e_devicemgr.gesture_id, e_devicemgr.atomPalmRejectionMode, + XA_INTEGER, 8, PropModeReplace, &enable, 1); + } + else + { + e_devicemgr.palm_disabled = EINA_FALSE; + XIChangeProperty(e_devicemgr.disp, e_devicemgr.gesture_id, e_devicemgr.atomPalmRejectionMode, + XA_INTEGER, 8, PropModeReplace, &disable, 1); + } + goto out; + } + if (e->atom == ECORE_X_ATOM_NET_ACTIVE_WINDOW && e->win == e_devicemgr.rootWin) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "active window is changed. Try to Change gesture property. id: %d, atom: %d, enable: %d\n", + e_devicemgr.gesture_id, e_devicemgr.atomWindowStackisChanged, enable); + XIChangeProperty(e_devicemgr.disp, e_devicemgr.gesture_id, e_devicemgr.atomWindowStackisChanged, + XA_INTEGER, 8, PropModeReplace, &enable, 1); + + if(e_devicemgr.palmDisablingWin == -1) + goto out; + + Ecore_X_Window highlight_win; + + res = ecore_x_window_prop_window_get(e_devicemgr.rootWin, ECORE_X_ATOM_NET_ACTIVE_WINDOW, &highlight_win, 1); + if (res <=0) + goto out; + + if (e_devicemgr.palm_disabled == EINA_FALSE && e_devicemgr.palmDisablingWin == highlight_win) + { + e_devicemgr.palm_disabled = EINA_TRUE; + XIChangeProperty(e_devicemgr.disp, e_devicemgr.gesture_id, e_devicemgr.atomPalmRejectionMode, + XA_INTEGER, 8, PropModeReplace, &enable, 1); + } + else if (e_devicemgr.palm_disabled == EINA_TRUE) + { + e_devicemgr.palm_disabled = EINA_FALSE; + XIChangeProperty(e_devicemgr.disp, e_devicemgr.gesture_id, e_devicemgr.atomPalmRejectionMode, + XA_INTEGER, 8, PropModeReplace, &disable, 1); + } + goto out; + } +out: + return 1; +} + +static int _e_devicemgr_cb_window_destroy(void *data, int ev_type, void *ev) +{ + Ecore_X_Event_Window_Destroy *e = ev; + int disable = 0; + int no_window = -1; + + if (e_devicemgr.palmDisablingWin != -1 && e->win == e_devicemgr.palmDisablingWin) + { + XIChangeProperty(e_devicemgr.disp, e_devicemgr.gesture_id, e_devicemgr.atomPalmRejectionMode, + XA_INTEGER, 8, PropModeReplace, &disable, 1); + ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomPalmDisablingWinRunning, &no_window, 1); + e_devicemgr.palmDisablingWin = -1; + e_devicemgr.palm_disabled = EINA_FALSE; + } + return 1; +} + +static int +_e_devicemgr_cb_event_generic(void *data, int ev_type, void *event) +{ + Ecore_X_Event_Generic *e = (Ecore_X_Event_Generic *)event; + XIDeviceEvent *evData = (XIDeviceEvent *)(e->data); + + if (e->extension != e_devicemgr.xi2_opcode) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Invalid event !(extension:%d, evtype:%d)\n", __FUNCTION__, e->extension, e->evtype); + return 1; + } + + if (!evData || evData->send_event) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Generic event data is not available or the event was sent via XSendEvent (and will be ignored) !\n", __FUNCTION__); + return 1; + } + switch (e->evtype) + { + case XI_HierarchyChanged: + _e_devicemgr_xi2_device_hierarchy_handler((XIHierarchyEvent *)evData); + break; + + case XI_DeviceChanged: + _e_devicemgr_xi2_device_changed_handler((XIDeviceChangedEvent *)evData); + break; + + case XI_PropertyEvent: + _e_devicemgr_xi2_device_property_handler((XIPropertyEvent *)evData); + break; + } + + return 1; +} + +static int +_e_devicemgr_cb_zone_add(void *data, int ev_type, void *event) +{ + E_Event_Zone_Add *ev; + E_Zone *zone; + Eina_List *l; + + ev = event; + zone = ev->zone; + if (!zone || !zone->name) return 1; + + l = eina_list_data_find_list(e_devicemgr.zones, zone); + if (l) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_add] zone exists already in zone list !\n"); + return 1; + } + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_add] z->name=%s, z->w=%d, z->h=%d, z->x=%d, z->y=%d\n", + zone->name, zone->w, zone->h, zone->x, zone->y); + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_add] z->useful_geometry.w=%d, z->useful_geometry.h=%d, z->useful_geometry.x=%d, z->useful_geometry.y=%d\n", + zone->useful_geometry.w, zone->useful_geometry.h, zone->useful_geometry.x, zone->useful_geometry.y); + + e_devicemgr.zones = eina_list_append(e_devicemgr.zones, zone); + e_devicemgr.num_zones++; + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_add] num_zones=%d\n", e_devicemgr.num_zones); + + return 1; +} + +static int +_e_devicemgr_cb_zone_del(void *data, int ev_type, void *event) +{ + E_Event_Zone_Del *ev; + E_Zone *zone; + Eina_List *l; + + ev = event; + zone = ev->zone; + if (!zone || !zone->name) return 1; + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_del] z->name=%s, z->w=%d, z->h=%d, z->x=%d, z->y=%d\n", + zone->name, zone->w, zone->h, zone->x, zone->y); + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_del] z->useful_geometry.w=%d, z->useful_geometry.h=%d, z->useful_geometry.x=%d, z->useful_geometry.y=%d\n", + zone->useful_geometry.w, zone->useful_geometry.h, zone->useful_geometry.x, zone->useful_geometry.y); + + if (e_devicemgr.num_zones < 2)//basic zone + additional zone(s) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_del] Zone list needs to be checked into !\n"); + return 1; + } + + l = eina_list_data_find_list(e_devicemgr.zones, zone); + if (!l) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_del] zone doesn't exist in zone list !\n"); + return 1; + } + + if (e_devicemgr.num_zones == 2 && e_devicemgr.virtual_touchpad_id > 0) + { + ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt, + ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_SHUTDOWN, 0, 0, 0, 0); + } + + e_devicemgr.zones = eina_list_remove(e_devicemgr.zones, zone); + e_devicemgr.num_zones--; + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][zone_del] num_zones=%d\n", e_devicemgr.num_zones); + + return 1; +} + +static void +_e_devicemgr_hook_border_resize_end(void *data, void *border) +{ + E_Border *bd = (E_Border *)border; + if (!bd) return; + + e_devicemgr.virtual_touchpad_pointed_window_info[0] = bd->x + bd->client_inset.l; + e_devicemgr.virtual_touchpad_pointed_window_info[1] = bd->y + bd->client_inset.t; + e_devicemgr.virtual_touchpad_pointed_window_info[2] = bd->client.w; + e_devicemgr.virtual_touchpad_pointed_window_info[3] = bd->client.h; + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][hook_border_resize_end] application win=0x%x, px=%d, py=%d, pw=%d, ph=%d\n", bd->client.win, + e_devicemgr.virtual_touchpad_pointed_window_info[0], e_devicemgr.virtual_touchpad_pointed_window_info[1], + e_devicemgr.virtual_touchpad_pointed_window_info[2], e_devicemgr.virtual_touchpad_pointed_window_info[3]); +} + +static void +_e_devicemgr_hook_border_move_end(void *data, void *border) +{ + E_Border *bd = (E_Border *)border; + if (!bd) return; + + e_devicemgr.virtual_touchpad_pointed_window_info[0] = bd->x + bd->client_inset.l; + e_devicemgr.virtual_touchpad_pointed_window_info[1] = bd->y + bd->client_inset.t; + e_devicemgr.virtual_touchpad_pointed_window_info[2] = bd->client.w; + e_devicemgr.virtual_touchpad_pointed_window_info[3] = bd->client.h; + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][hook_border_move_end] application win=0x%x, px=%d, py=%d, pw=%d, ph=%d\n", bd->client.win, + e_devicemgr.virtual_touchpad_pointed_window_info[0], e_devicemgr.virtual_touchpad_pointed_window_info[1], + e_devicemgr.virtual_touchpad_pointed_window_info[2], e_devicemgr.virtual_touchpad_pointed_window_info[3]); +} + +static Eina_Bool +_e_devicemgr_cb_mouse_in(void *data, int type, void *event) +{ + int px, py; + int pw, ph; + int vw, vh; + E_Border *bd; + unsigned int val = 0; + Ecore_X_Event_Mouse_In *ev = event; + + if (!e_devicemgr.virtual_multitouch_done) return ECORE_CALLBACK_PASS_ON; + + bd = e_border_find_by_window(ev->event_win); + if (!bd) + { + if (e_devicemgr.rootWin == ecore_x_window_parent_get(ev->event_win)) + { + + if (!e_devicemgr.virtual_multitouch_done && e_devicemgr.virtual_touchpad_pointed_window != 0) + return ECORE_CALLBACK_PASS_ON; + + e_devicemgr.virtual_touchpad_pointed_window = 0; + ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt, + ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_POINTED_WINDOW, 0, 0, 0, 0); + _e_devicemgr_update_input_transform_matrix(EINA_TRUE/* reset */); + return ECORE_CALLBACK_PASS_ON; + } + + return ECORE_CALLBACK_PASS_ON; + } + + if (bd->zone->id == 0) + { + return ECORE_CALLBACK_PASS_ON; + } + + e_devicemgr.virtual_touchpad_pointed_window_info[0] = bd->x + bd->client_inset.l; + e_devicemgr.virtual_touchpad_pointed_window_info[1] = bd->y + bd->client_inset.t; + e_devicemgr.virtual_touchpad_pointed_window_info[2] = bd->client.w; + e_devicemgr.virtual_touchpad_pointed_window_info[3] = bd->client.h; + e_devicemgr.virtual_touchpad_pointed_window = bd->client.win; + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][cb_mouse_in] application win=0x%x, px=%d, py=%d, pw=%d, ph=%d\n", bd->client.win, + e_devicemgr.virtual_touchpad_pointed_window_info[0], e_devicemgr.virtual_touchpad_pointed_window_info[1], + e_devicemgr.virtual_touchpad_pointed_window_info[2], e_devicemgr.virtual_touchpad_pointed_window_info[3]); + ecore_x_client_message32_send(e_devicemgr.virtual_touchpad_window, e_devicemgr.atomVirtualTouchpadInt, + ECORE_X_EVENT_MASK_NONE, E_VIRTUAL_TOUCHPAD_POINTED_WINDOW, + e_devicemgr.virtual_touchpad_pointed_window, 0, 0, 0); + + return ECORE_CALLBACK_PASS_ON; +} + +static Eina_Bool +_e_devicemgr_get_zones(void) +{ + Eina_List *ml; + E_Manager *man; + + if (e_devicemgr.zones) + return EINA_FALSE; + + EINA_LIST_FOREACH(e_manager_list(), ml, man) + { + if (man) + { + Eina_List *cl; + E_Container *con; + + EINA_LIST_FOREACH(man->containers, cl, con) + { + if (con) + { + Eina_List *zl; + E_Zone *z; + + EINA_LIST_FOREACH(con->zones, zl, z) + { + if (z) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][_e_devicemgr_get_zones] z->name=%s, z->w=%d, z->h=%d, z->x=%d, z->y=%d\n", + z->name, z->w, z->h, z->x, z->y); + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][_e_devicemgr_get_zones] z->useful_geometry.w=%d, z->useful_geometry.h=%d, z->useful_geometry.x=%d, z->useful_geometry.y=%d\n", + z->useful_geometry.w, z->useful_geometry.h, z->useful_geometry.x, z->useful_geometry.y); + e_devicemgr.zones = eina_list_append(e_devicemgr.zones, z); + e_devicemgr.num_zones++; + } + } + } + } + } + } + + return (e_devicemgr.zones) ? EINA_TRUE : EINA_FALSE; +} + +static int +_e_devicemgr_marshalize_string (char* buf, int num, char* srcs[]) +{ + int i; + char * p = buf; + + for (i=0; inoutput != 0)) + { + for ( i = 0 ; i noutput ; i++ ) + { + output_info = XRRGetOutputInfo(e_devicemgr.disp, res, res->outputs[i]); + if (output_info && output_info->name && !strncmp(output_info->name, "LVDS1", 5)) + { + e_devicemgr.output = res->outputs[i]; + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][_e_devicemgr_init_output] LVDS1 was found !\n"); + XRRFreeOutputInfo(output_info); + break; + } + else + { + e_devicemgr.output = res->outputs[i]; + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][_e_devicemgr_init_output] LVDS1 was not found yet !\n"); + } + + if (output_info) XRRFreeOutputInfo(output_info); + } + } + + if (!e_devicemgr.output) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][_e_devicemgr_init_output] Failed to init output !\n"); + } + + if (res) + XRRFreeScreenResources(res); +} + +static void +_e_devicemgr_init_transform_matrix(void) +{ + memset(e_devicemgr.tmatrix, 0, sizeof(e_devicemgr.tmatrix)); + + e_devicemgr.tmatrix[8] = 1.0f; + e_devicemgr.tmatrix[0] = 1.0f; + e_devicemgr.tmatrix[4] = 1.0f; +} + +static void +_e_devicemgr_init_input(void) +{ + int i; + int ndevices; + XIDeviceInfo *dev, *info = NULL; + DeviceMgr_Device_Info *data = NULL; + + if (e_devicemgr.xi2_opcode < 0) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to initialize input !\n", __FUNCTION__); + return; + } + + info = XIQueryDevice(e_devicemgr.disp, XIAllDevices, &ndevices); + + if (!info) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] There is no queried XI device.\n", __FUNCTION__); + return; + } + + for (i = 0; i < ndevices ; i++) + { + dev = &info[i]; + + switch (dev->use) + { + case XISlavePointer: + if (strcasestr(dev->name, "Virtual core XTEST pointer")) + { + e_devicemgr.vcp_xtest_pointer_id = dev->deviceid; + continue; + } + if (strcasestr(dev->name, "XTEST") +#ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_ + && strncmp(dev->name, TOUCH_DEVICE_NAME, LEN_TOUCH_DEVICE_NAME) +#endif //_F_SUPPORT_XTEST_TOUCH_EVENT_ + ) continue; + if (strcasestr(dev->name, "keyboard")) goto handle_keyboard; + if (1==_e_devicemgr_check_device_type(dev->deviceid, E_DEVICEMGR_GAMEPAD, dev->name)) goto handle_keyboard; + + data = malloc(sizeof(DeviceMgr_Device_Info)); + + if (!data) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__); + goto out; + } + + data->id = dev->deviceid; + data->name = eina_stringshare_add(dev->name); + data->use = dev->use; + data->master_id = dev->attachment; + if (1==_e_devicemgr_check_device_type(dev->deviceid, E_DEVICEMGR_TOUCHSCREEN, dev->name)) + { + //Now we have a touchscreen device. + data->type = E_DEVICEMGR_TOUCHSCREEN; + e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data); + e_devicemgr.num_touchscreen_devices++; + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Slave touchscreen device (id=%d, name=%s, num_touchscreen_devices=%d) was added/enabled !\n", + __FUNCTION__, dev->deviceid, dev->name, e_devicemgr.num_touchscreen_devices); + } + else + { + //Now we have a mouse. + data->type = E_DEVICEMGR_MOUSE; + e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data); + e_devicemgr.num_pointer_devices++; + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Slave pointer device (id=%d, name=%s, num_pointer_devices=%d) was added/enabled !\n", + __FUNCTION__, dev->deviceid, dev->name, e_devicemgr.num_pointer_devices); + } + break; + + case XISlaveKeyboard: + if (strcasestr(dev->name, "Virtual core XTEST keyboard")) + { + e_devicemgr.vck_xtest_keyboard_id = dev->deviceid; + continue; + } + + if (strcasestr(dev->name, "XTEST") +#ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_ + && strncmp(dev->name, FUNCTION_KEY_DEVICE_NAME, LEN_FUNCTION_KEY_DEVICE_NAME) +#endif //_F_SUPPORT_XTEST_TOUCH_EVENT_ + ) continue; + + if (strcasestr(dev->name, "Gesture"))//gesture + { + //Now we have a gesture device. + data = malloc(sizeof(DeviceMgr_Device_Info)); + if (!data) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__); + goto out; + } + data->id = dev->deviceid; + data->name = eina_stringshare_add(dev->name); + data->master_id = dev->attachment; + + e_devicemgr.gesture_id = data->id; + e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data); + + _e_devicemgr_detach_slave(e_devicemgr.gesture_id); + + break; + } +handle_keyboard: + data = malloc(sizeof(DeviceMgr_Device_Info)); + + if (!data) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__); + goto out; + } + + data->use = dev->use; + + if (strcasestr(dev->name, "keyboard") && !strcasestr(dev->name, "XTEST" ))//keyboard + { + //Now we have a keyboard device + data->id = dev->deviceid; + data->name = eina_stringshare_add(dev->name); + data->type = E_DEVICEMGR_KEYBOARD; + data->master_id = dev->attachment; + + e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data); + e_devicemgr.num_keyboard_devices++; + _e_devicemgr_lockmodifier_set(); + + if (e_devicemgr.num_keyboard_devices >= 1) + { + _e_devicemgr_set_keyboard_exist((unsigned int)e_devicemgr.num_keyboard_devices, 1); + } + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Slave keyboard device (id=%d, name=%s, num_keyboard_devices=%d) was added/enabled !\n", + __FUNCTION__, dev->deviceid, dev->name, e_devicemgr.num_keyboard_devices); + } + else if (1==_e_devicemgr_check_device_type(dev->deviceid, E_DEVICEMGR_GAMEPAD, info->name)) + { + //Now we have a game pad device. + data->id = dev->deviceid; + data->name = eina_stringshare_add(dev->name); + data->type = E_DEVICEMGR_GAMEPAD; + data->master_id = dev->attachment; + + e_devicemgr.gamepad_id = data->id; + + e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data); + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] game pad device (id=%d, name=%s) was added/enabled !\n", + __FUNCTION__, dev->deviceid, dev->name); + } + else//HW key + { + data->type = E_DEVICEMGR_HWKEY; + data->id = dev->deviceid; + data->name = eina_stringshare_add(dev->name); + data->master_id = dev->attachment; + + e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data); + e_devicemgr.num_hwkey_devices++; + } + break; + + case XIFloatingSlave: + if (strcasestr(dev->name, "Gesture"))//gesture + { + //Now we have a gesture device. + data = malloc(sizeof(DeviceMgr_Device_Info)); + if (!data) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__); + goto out; + } + data->id = dev->deviceid; + data->name = eina_stringshare_add(dev->name); + data->master_id = dev->attachment; + + e_devicemgr.gesture_id = data->id; + e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data); + + break; + } + if (1!=_e_devicemgr_check_device_type(dev->deviceid, E_DEVICEMGR_TOUCHSCREEN, dev->name)) continue; + + //Now we have a touchscreen device. + data = malloc(sizeof(DeviceMgr_Device_Info)); + + if (!data) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__); + goto out; + } + + data->id = dev->deviceid; + data->name = eina_stringshare_add(dev->name); + data->use = dev->use; + data->type = E_DEVICEMGR_TOUCHSCREEN; + data->master_id = dev->attachment; + e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data); + e_devicemgr.num_touchscreen_devices++; + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] FloatingSlave touchscreen device (id=%d, name=%s, num_touchscreen_devices=%d) was added/enabled !\n", + __FUNCTION__, dev->deviceid, dev->name, e_devicemgr.num_touchscreen_devices); + _e_devicemgr_append_prop_touchscreen_device_id(dev->deviceid); + break; + + case XIMasterPointer: + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] XIMasterPointer (VCP) (id=%d, name=%s)\n", __FUNCTION__, dev->deviceid, dev->name); + e_devicemgr.vcp_id = dev->deviceid; + break; + + case XIMasterKeyboard: + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] XIMasterKeyboard (VCK) (id=%d, name=%s)\n", __FUNCTION__, dev->deviceid, dev->name); + e_devicemgr.vck_id = dev->deviceid; + break; + } + } + +out: + XIFreeDeviceInfo(info); +} + +static void +_e_devicemgr_xi2_device_property_handler(XIPropertyEvent *event) +{ + if ((event->property == e_devicemgr.atomRelativeMoveStatus)) + { + if( (event->what) && !(e_devicemgr.cursor_show_ack) ) + { + e_devicemgr.cursor_show = 1; + e_devicemgr.rel_move_deviceid = event->deviceid; + _e_devicemgr_enable_mouse_cursor(e_devicemgr.cursor_show); + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Relative Move Status !(e_devicemgr.cursor_show=%d)\n", e_devicemgr.cursor_show); + + e_devicemgr.cursor_show_ack = 1; + XIChangeProperty(e_devicemgr.disp, event->deviceid, e_devicemgr.atomRelativeMoveAck, XA_INTEGER, 8, + PropModeReplace, &e_devicemgr.cursor_show_ack, 1); + } + else if( !(event->what) ) + { + e_devicemgr.cursor_show = 0; + e_devicemgr.cursor_show_ack = 0; + e_devicemgr.rel_move_deviceid = event->deviceid; + _e_devicemgr_enable_mouse_cursor(e_devicemgr.cursor_show); + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] Relative Move Status !(e_devicemgr.cursor_show=%d)\n", e_devicemgr.cursor_show); + } + } +} + +static void +_e_devicemgr_xi2_device_changed_handler(XIDeviceChangedEvent *event) +{ + if (event->reason == XISlaveSwitch) + { + _e_devicemgr_slave_switched(event->deviceid, event->sourceid); + } + else if (event->reason == XIDeviceChange) + { + _e_devicemgr_device_changed(event->deviceid, event->sourceid); + } +} + +static void +_e_devicemgr_xi2_device_hierarchy_handler(XIHierarchyEvent *event) +{ + int i; + + if (event->flags & XIMasterAdded || event->flags & XIMasterRemoved) + { + for( i = 0 ; i < event->num_info ; i++ ) + { + if (event->info[i].flags & XIMasterAdded) + { + _e_devicemgr_master_pointer_added(event->info[i].deviceid); + } + else if (event->info[i].flags & XIMasterRemoved) + { + _e_devicemgr_master_pointer_removed(event->info[i].deviceid); + } + } + } + + if (event->flags & XISlaveAdded || event->flags & XISlaveRemoved) + { + for( i = 0 ; i < event->num_info ; i++ ) + { + if (event->info[i].flags & XISlaveAdded) + { + if (1==_e_devicemgr_check_device_type(event->info[i].deviceid, E_DEVICEMGR_GAMEPAD, "Gamepad")) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Slave gamepad device is added!\n", __FUNCTION__); + e_devicemgr.gamepad_id = event->info[i].deviceid; + break; + } + } + else if (event->info[i].flags & XISlaveRemoved) + { + if (event->info[i].deviceid == e_devicemgr.gamepad_id) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Slave gamepad device is removed!\n", __FUNCTION__); + e_devicemgr.gamepad_id = -1; + break; + } + } + } + } + + if (event->flags & XIDeviceEnabled || event->flags & XIDeviceDisabled) + { + for( i = 0 ; i < event->num_info ; i++ ) + { + if (event->info[i].flags & XIDeviceEnabled) + { + _e_devicemgr_device_enabled(event->info[i].deviceid, event->info[i].use); + } + else if (event->info[i].flags & XIDeviceDisabled) + { + _e_devicemgr_device_disabled(event->info[i].deviceid, event->info[i].use); + } + } + } +} + +static int +_e_devicemgr_check_device_type(int deviceid, DeviceMgrDeviceType type, const char* devname) +{ + char *tmp = NULL; + Atom act_type; + unsigned long nitems, bytes_after; + unsigned char *data = NULL, *ptr; + int j, act_format, ret = 0; + + if (type != E_DEVICEMGR_TOUCHSCREEN && type != E_DEVICEMGR_MOUSE && type != E_DEVICEMGR_GAMEPAD) return 0; + + if (XIGetProperty(e_devicemgr.disp, deviceid, e_devicemgr.atomAxisLabels, 0, 1000, False, + XA_ATOM, &act_type, &act_format, + &nitems, &bytes_after, &data) != Success) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][check_device_type] Failed to get XI2 Axis device property !(deviceid=%d)\n", deviceid); + goto out; + } + + if (!nitems || !data) goto out; + + ptr = data; + + for (j = 0; j < nitems; j++) + { + switch(act_type) + { + case XA_ATOM: + { + Ecore_X_Atom atomTemp = *(Ecore_X_Atom*)ptr; + if (!atomTemp) goto out; + + tmp = ecore_x_atom_name_get(atomTemp); + if (!tmp) break; + + if ((type == E_DEVICEMGR_TOUCHSCREEN) && (strcasestr(tmp, "Abs X") || strcasestr(tmp, "Abs MT Position X")) && !strcasestr(devname, "maru")) + { + ret = 1; + goto out; + } + else if (type == E_DEVICEMGR_MOUSE && strcasestr(tmp, "Rel X")) + { + ret = 1; + goto out; + } + else if (type == E_DEVICEMGR_GAMEPAD && (strcasestr(tmp, "Abs Hat 0 X") || strcasestr(tmp, "Abs Hat 0 Y"))) + { + goto gamepad_handling; + } + free(tmp); + tmp = NULL; + } + break; + } + + ptr += act_format/8; + } + +out: + if (data) XFree(data); + if (tmp) free(tmp); + + return ret; + +gamepad_handling: + + if (data) XFree(data); + if (tmp) free(tmp); + data = NULL; + tmp = NULL; + + if (XIGetProperty(e_devicemgr.disp, deviceid, e_devicemgr.atomButtonLabels, 0, 1000, False, + XA_ATOM, &act_type, &act_format, + &nitems, &bytes_after, &data) != Success) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][check_device_type] Failed to get XI2 Button device property !(deviceid=%d)\n", deviceid); + goto out; + } + + if (!nitems) goto out; + + ptr = data; + + for (j = 0; j < nitems; j++) + { + switch(act_type) + { + case XA_ATOM: + { + Ecore_X_Atom atomTemp = *(Ecore_X_Atom*)ptr; + if (!atomTemp) goto out; + + tmp = ecore_x_atom_name_get(atomTemp); + if(tmp) + { + if (strcasestr(tmp, "Button A") || strcasestr(tmp, "Button B")) + { + ret = 1; + goto out; + } + free(tmp); + tmp = NULL; + } + } + break; + } + + ptr += act_format/8; + } + goto out; +} + +static void +_e_devicemgr_device_enabled(int id, int type) +{ + int ndevices; + XIDeviceInfo *info = NULL; + DeviceMgr_Device_Info *data = NULL; + + info = XIQueryDevice(e_devicemgr.disp, id, &ndevices); + + if (!info || ndevices <= 0) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] There is no queried XI device. (device id=%d, type=%d)\n", __FUNCTION__, id, type); + goto out; + } + + switch(info->use) + { + case XISlavePointer: + if (strcasestr(info->name, "XTEST") +#ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_ + && strncmp(info->name, TOUCH_DEVICE_NAME, LEN_TOUCH_DEVICE_NAME) +#endif //_F_SUPPORT_XTEST_TOUCH_EVENT_ + ) goto out; + if (strcasestr(info->name, "keyboard")) goto handle_keyboard; + if (1==_e_devicemgr_check_device_type(id, E_DEVICEMGR_GAMEPAD, info->name)) goto handle_keyboard; + + data = malloc(sizeof(DeviceMgr_Device_Info)); + + if (!data) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__); + goto out; + } + + data->id = id; + data->name = eina_stringshare_add(info->name); + data->master_id = info->attachment; + data->use = info->use; + + if (1==_e_devicemgr_check_device_type(id, E_DEVICEMGR_TOUCHSCREEN, info->name)) + { + //Now we have a touchscreen device. + data->type = E_DEVICEMGR_TOUCHSCREEN; + if (strcasestr(data->name, "virtual") && strcasestr(data->name, "multitouch")) + { + _e_devicemgr_virtual_multitouch_helper_init(id); + } + e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data); + e_devicemgr.num_touchscreen_devices++; + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Slave touchscreen device (id=%d, name=%s, num_touchscreen_devices=%d) was added/enabled !\n", + __FUNCTION__, id, info->name, e_devicemgr.num_touchscreen_devices); + } + else + { + //Now we have a mouse. + data->type = E_DEVICEMGR_MOUSE; + e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data); + e_devicemgr.num_pointer_devices++; + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Slave pointer device (id=%d, name=%s, num_pointer_devices=%d) was added/enabled !\n", + __FUNCTION__, id, info->name, e_devicemgr.num_pointer_devices); + if (strcasestr(info->name, E_VIRTUAL_TOUCHPAD_NAME)) + { + e_devicemgr.virtual_touchpad_id = id; + _e_devicemgr_virtual_touchpad_helper_enable(EINA_TRUE); + } + } + break; + + case XISlaveKeyboard: + if (strcasestr(info->name, "XTEST") +#ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_ + && strncmp(info->name, FUNCTION_KEY_DEVICE_NAME, LEN_FUNCTION_KEY_DEVICE_NAME) +#endif //_F_SUPPORT_XTEST_TOUCH_EVENT_ + ) goto out; +handle_keyboard: + data = malloc(sizeof(DeviceMgr_Device_Info)); + + if (!data) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__); + goto out; + } + + if (strcasestr(info->name, "keyboard"))//keyboard + { + int ret_val=-1; + //Now we have a keyboard device. + data->id = id; + data->name = eina_stringshare_add(info->name); + data->type = E_DEVICEMGR_KEYBOARD; + data->master_id = info->attachment; + + e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data); + e_devicemgr.num_keyboard_devices++; + + if (e_devicemgr.num_keyboard_devices >= 1) + _e_devicemgr_set_keyboard_exist((unsigned int)e_devicemgr.num_keyboard_devices, 1); + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Slave keyboard device (id=%d, name=%s, num_keyboard_devices=%d) was added/enabled !\n", + __FUNCTION__, id, info->name, e_devicemgr.num_keyboard_devices); + int res = ecore_x_window_prop_card32_get(e_devicemgr.input_window, e_devicemgr.atomExKeyboardEnabled, &ret_val, 1); + if(res <= 0) + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] fail to get keyboard enable prop\n"); + if(ret_val == 0) + { + if(_e_devicemgr_detach_slave(data->id) == EINA_FALSE) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] : fail to detach slave device(%d) \n", data->id); + } + } + } + else if (1==_e_devicemgr_check_device_type(id, E_DEVICEMGR_GAMEPAD, info->name)) + { + int ret_val=-1; + //Now we have a game pad device. + data->id = id; + data->name = eina_stringshare_add(info->name); + data->type = E_DEVICEMGR_GAMEPAD; + data->master_id = info->attachment; + + e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data); + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] game pad device (id=%d, name=%s) was added/enabled !\n", + __FUNCTION__, id, info->name); + + int res = ecore_x_window_prop_card32_get(e_devicemgr.input_window, e_devicemgr.atomExKeyboardEnabled, &ret_val, 1); + if(res <= 0) + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] fail to get keyboard enable prop\n"); + if(ret_val == 0) + { + if(_e_devicemgr_detach_slave(data->id) == EINA_FALSE) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] : fail to detach slave device(%d) \n", data->id); + } + } + } + else//HW key + { + data->type = E_DEVICEMGR_HWKEY; + data->id = id; + data->name = eina_stringshare_add(info->name); + + e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data); + e_devicemgr.num_hwkey_devices++; + } + + _e_devicemgr_lockmodifier_set(); + break; + + case XIFloatingSlave: + if (1 == _e_devicemgr_check_device_type(id, E_DEVICEMGR_TOUCHSCREEN, info->name)) + { + //Now we have a floating touchscreen device. + data = malloc(sizeof(DeviceMgr_Device_Info)); + + if (!data) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to allocate memory for device info !\n", __FUNCTION__); + goto out; + } + + data->id = id; + data->name = eina_stringshare_add(info->name); + data->master_id = info->attachment; + data->use = info->use; + data->type = E_DEVICEMGR_TOUCHSCREEN; + e_devicemgr.device_list = eina_list_append(e_devicemgr.device_list, data); + e_devicemgr.num_touchscreen_devices++; + + _e_devicemgr_append_prop_touchscreen_device_id(id); + + if (strcasestr(info->name, "virtual") && strcasestr(info->name, "multitouch")) + { + _e_devicemgr_virtual_multitouch_helper_init(id); + } + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] FloatingSlave touchscreen device (id=%d, name=%s, num_touchscreen_devices=%d) was added/enabled !\n", + __FUNCTION__, id, info->name, e_devicemgr.num_touchscreen_devices); + } + break; + } + +out: + if (info) XIFreeDeviceInfo(info); +} + +static void +_e_devicemgr_device_disabled(int id, int type) +{ + Eina_List* l; + DeviceMgr_Device_Info *data; + + if (!e_devicemgr.device_list) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] device list is empty ! something's wrong ! (id=%d, type=%d)\n", __FUNCTION__, id, type); + goto out; + } + + EINA_LIST_FOREACH(e_devicemgr.device_list, l, data) + { + if (data && data->id == id) + { + switch( data->type ) + { + case E_DEVICEMGR_HWKEY: + e_devicemgr.num_hwkey_devices--; + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Slave H/W key device (id=%d, name=%s, type=%d) was removed/disabled !\n", + __FUNCTION__, id, data->name, type); + + e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data); + free(data); + goto out; + + case E_DEVICEMGR_KEYBOARD: + e_devicemgr.num_keyboard_devices--; + + if (e_devicemgr.num_keyboard_devices <= 0) + { + e_devicemgr.num_keyboard_devices = 0; + _e_devicemgr_set_keyboard_exist(0, 0); + } + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Slave keyboard device (id=%d, name=%s, type=%d, num_keyboard_devices=%d) was removed/disabled !\n", + __FUNCTION__, id, data->name, type, e_devicemgr.num_keyboard_devices); + + e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data); + free(data); + goto out; + + case E_DEVICEMGR_MOUSE: + e_devicemgr.num_pointer_devices--; + + if (e_devicemgr.num_pointer_devices <= 0) + { + e_devicemgr.num_pointer_devices = 0; + } + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Slave pointer device (id=%d, name=%s, type=%d, num_pointer_devices=%d) was removed/disabled !\n", + __FUNCTION__, id, data->name, type, e_devicemgr.num_pointer_devices); + if (e_devicemgr.virtual_touchpad_id == id) + { + e_devicemgr.virtual_touchpad_id = -1; + _e_devicemgr_virtual_touchpad_helper_enable(EINA_FALSE); + } + e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data); + free(data); + goto out; + + case E_DEVICEMGR_TOUCHSCREEN: + if (strcasestr(data->name, "virtual") && strcasestr(data->name, "multitouch")) + _e_devicemgr_virtual_multitouch_helper_fini(); + e_devicemgr.num_touchscreen_devices--; + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] %sSlave touchscreen device (id=%d, name=%s, type=%d, num_touchscreen_devices=%d) was removed/disabled !\n", + __FUNCTION__, (data->use == XISlavePointer) ? "" : "Floating", id, data->name, type, e_devicemgr.num_touchscreen_devices); + + if (data->use == XIFloatingSlave) + _e_devicemgr_remove_prop_touchscreen_device_id(data->id); + + e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data); + free(data); + goto out; + + case E_DEVICEMGR_GAMEPAD: + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Slave gamepad device (id=%d, name=%s, type=%d) was removed/disabled !\n", + __FUNCTION__, id, data->name, type); + + e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data); + free(data); + goto out; + + default: + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Unknown type of device ! (id=%d, type=%d, name=%s, device type=%d)\n", + __FUNCTION__, data->id, type, data->name, data->type); + e_devicemgr.device_list = eina_list_remove(e_devicemgr.device_list, data); + free(data); + goto out; + } + } + } + +out: + return; +} + +static void +_e_devicemgr_master_pointer_added(int id) +{ + int ndevices; + XIDeviceInfo *info = NULL; + + info = XIQueryDevice(e_devicemgr.disp, id, &ndevices); + + if (!info || ndevices <= 0) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][master_pointer_added] There is no queried XI device. (device id=%d)\n", id); + goto out; + } + + if (info->use != XIMasterPointer) goto out; + + //Now we have a MasterPointer. + if (strcasestr(E_NEW_MASTER_NAME" pointer", info->name)) + { + //SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][master_pointer_added] XIMasterPointer is added !(id=%d, name=%s)\n", info->deviceid, info->name); + e_devicemgr.new_master_pointer_id = info->deviceid; + + Eina_List *l; + Eina_List *l2; + int touchscreen_id = -1; + DeviceMgr_Device_Info *devinfo; + + EINA_LIST_FOREACH_SAFE(e_devicemgr.device_list, l, l2, devinfo) + { + if (!devinfo) continue; + if (devinfo->type == E_DEVICEMGR_TOUCHSCREEN) + { + touchscreen_id = devinfo->id; + break; + } + } + + if (touchscreen_id != -1) + _e_devicemgr_reattach_slave + (touchscreen_id, e_devicemgr.new_master_pointer_id); + } + +out: + if (info) XIFreeDeviceInfo(info); +} + +static void +_e_devicemgr_master_pointer_removed(int id) +{ + if (e_devicemgr.new_master_pointer_id == id) + { + //SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][master_pointer_removed] XIMasterPointer was removed ! (id=%d, name=%s)\n", + // id, E_NEW_MASTER_NAME" pointer"); + e_devicemgr.new_master_pointer_id = -1; + + Eina_List *l; + Eina_List *l2; + int touchscreen_id = -1; + DeviceMgr_Device_Info *devinfo; + + EINA_LIST_FOREACH_SAFE(e_devicemgr.device_list, l, l2, devinfo) + { + if (!devinfo) continue; + if (devinfo->type == E_DEVICEMGR_TOUCHSCREEN) + { + touchscreen_id = devinfo->id; + break; + } + } + + if (touchscreen_id != -1) + _e_devicemgr_reattach_slave + (touchscreen_id, e_devicemgr.vcp_id); + } +} + +static void +_e_devicemgr_slave_switched(int deviceid, int sourceid) +{ + unsigned int val; + Eina_List *l; + DeviceMgr_Device_Info *device_info; + + EINA_LIST_FOREACH(e_devicemgr.device_list, l, device_info) + { + if (!device_info || device_info->id!=sourceid) continue; + if (device_info->type==E_DEVICEMGR_TOUCHSCREEN) + { + val = 1; + ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomTouchInput, &val, 1); + } + else if (device_info->type==E_DEVICEMGR_MOUSE) + { + val = 0; + ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomTouchInput, &val, 1); + } + } +} + +static void +_e_devicemgr_device_changed(int deviceid, int sourceid) +{ + //SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][device_change_handler] deviceid:%d, sourceid:%d\n", deviceid, sourceid); +} + +static void +_e_devicemgr_append_prop_touchscreen_device_id(int id) +{ + unsigned int *prop_data = NULL, *new_data = NULL; + int ret, count, i; + + ret = ecore_x_window_prop_property_get(e_devicemgr.rootWin, e_devicemgr.atomMultitouchDeviceId, + ECORE_X_ATOM_CARDINAL, 32, (unsigned char **)&prop_data, &count); + if (!ret || !prop_data) + { + ecore_x_window_prop_property_set(e_devicemgr.rootWin, e_devicemgr.atomMultitouchDeviceId, + ECORE_X_ATOM_CARDINAL, 32, &id, 1); + } + else + { + new_data = (int *)calloc(1, sizeof(int)*count+1); + if (!new_data) + { + SLOG(LOG_WARN, "DEVICEMGR", "failed to allocate memory\n"); + if (prop_data) free(prop_data); + return; + } + for (i=0; i= count) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "id(%d) was not in multitouch device property\n"); + if (new_data) free(new_data); + if (prop_data) free(prop_data); + return; + } + if (new_data != NULL) new_data[j] = prop_data[i]; + j++; + } + } + ecore_x_window_prop_property_set(e_devicemgr.rootWin, e_devicemgr.atomMultitouchDeviceId, + ECORE_X_ATOM_CARDINAL, 32, new_data, count-1); + } + + if (new_data) free(new_data); + if (prop_data) free(prop_data); +} + +static void _e_devicemgr_enable_mouse_cursor(unsigned int val) +{ + if (!val) + { + _e_devicemgr_set_mouse_exist(0, 0); + } + else if (1 == val) + { + _e_devicemgr_set_mouse_exist(1, 0); + } +} + +static void +_e_devicemgr_set_confine_information(int deviceid, E_Zone *zone, Eina_Bool isset, int region[4], Eina_Bool pointer_warp, Eina_Bool confine) +{ + int confine_region[6]; + + if (isset && !zone && !region) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][set_confine_information] zone or region is needed for setting confine information !\n"); + return; + } + + if (isset) + { + if (zone) + { + confine_region[0] = zone->x; + confine_region[1] = zone->y; + confine_region[2] = zone->x + zone->w; + confine_region[3] = zone->y + zone->h; + //SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][set_confine_information][zone] x=%d, y=%d, w=%d, h=%d\n", confine_region[0], confine_region[1], confine_region[2], confine_region[3]); + } + else + { + confine_region[0] = region[0]; + confine_region[1] = region[1]; + confine_region[2] = region[2]; + confine_region[3] = region[3]; + //SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][set_confine_information][region] x=%d, y=%d, w=%d, h=%d\n", confine_region[0], confine_region[1], confine_region[2], confine_region[3]); + } + if (pointer_warp) confine_region[4] = 1; + else confine_region[4] = 0; + if (confine) confine_region[5] = 1; + else confine_region[5] = 0; + XIChangeProperty(e_devicemgr.disp, deviceid, e_devicemgr.atomVirtualTouchpadConfineRegion, + XA_INTEGER, 32, PropModeReplace, (unsigned char*)&confine_region[0], 6); + XFlush(e_devicemgr.disp); + XSync(e_devicemgr.disp, False); + } + else + { + confine_region[0] = 0; + XIChangeProperty(e_devicemgr.disp, deviceid, e_devicemgr.atomVirtualTouchpadConfineRegion, + XA_INTEGER, 32, PropModeReplace, (unsigned char*)&confine_region[0], 1); + XFlush(e_devicemgr.disp); + XSync(e_devicemgr.disp, False); + } +} + +static void +_e_devicemgr_set_mouse_exist(unsigned int val, int propset) +{ + if (!val) + { + char* cmds[] = {"e_devicemgr", "cursor_enable", "0", NULL }; + e_devicemgr.rroutput_buf_len = _e_devicemgr_marshalize_string (e_devicemgr.rroutput_buf,3, cmds); + + XRRChangeOutputProperty(e_devicemgr.disp, e_devicemgr.output, e_devicemgr.atomRROutput, XA_CARDINAL, 8, PropModeReplace, (unsigned char *)e_devicemgr.rroutput_buf, e_devicemgr.rroutput_buf_len); + XSync(e_devicemgr.disp, False); + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] cursor show = 0\n"); + + if (propset) ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomXMouseExist, &val, 1); + } + else if (1 == val) + { + char* cmds[] = {"e_devicemgr", "cursor_enable", "1", NULL }; + e_devicemgr.rroutput_buf_len = _e_devicemgr_marshalize_string (e_devicemgr.rroutput_buf,3, cmds); + + XRRChangeOutputProperty(e_devicemgr.disp, e_devicemgr.output, e_devicemgr.atomRROutput, XA_CARDINAL, 8, PropModeReplace, (unsigned char *)e_devicemgr.rroutput_buf, e_devicemgr.rroutput_buf_len); + XSync(e_devicemgr.disp, False); + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr] cursor show = 1\n"); + + if (propset) ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomXMouseExist, &val, 1); + } + else + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Invalid value for enabling cursor !(val=%d)\n", __FUNCTION__, val); + } +} + +static void +_e_devicemgr_set_keyboard_exist(unsigned int val, int is_connected) +{ + ecore_x_window_prop_card32_set(e_devicemgr.input_window, e_devicemgr.atomXExtKeyboardExist, &val, 1); +} + +static int +_e_devicemgr_get_lockmodifier_mask(void) +{ + Window dummy1, dummy2; + int dummy3, dummy4, dummy5, dummy6; + unsigned int mask; + + XQueryPointer(e_devicemgr.disp, DefaultRootWindow(e_devicemgr.disp), &dummy1, &dummy2, + &dummy3, &dummy4, &dummy5, &dummy6, &mask); + return (mask & (NumLockMask | CapsLockMask)); +} + +static int +_e_devicemgr_xkb_set_on(unsigned int mask) +{ + if (!mask) return 0; + + XkbLockModifiers(e_devicemgr.disp, XkbUseCoreKbd, mask, mask); + return 1; +} + +static int +_e_devicemgr_lockmodifier_set(void) +{ + unsigned int mask; + + if (e_devicemgr.xkb_available != EINA_TRUE) return -1; + + //Get current numlock/capslock status from Xserver + mask = _e_devicemgr_get_lockmodifier_mask(); + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][lockmodifier_set] NumLock mask=%d, CapsLock mask=%d\n", + NumLockMask & mask, CapsLockMask & mask); + + //If one of lockmodiers is set, try to turn it on for all keyboard devices. + if (mask && _e_devicemgr_xkb_set_on(mask)) return 1; + + return 0; +} + +static Eina_Bool +_e_devicemgr_create_master_device(char* master_name) +{ + int ret; + XIAddMasterInfo c; + + if (!master_name) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][create_master_device] name of master device is needed !\n"); + return EINA_FALSE; + } + + c.type = XIAddMaster; + c.name = master_name; + c.send_core = 1; + c.enable = 1; + + ret = XIChangeHierarchy(e_devicemgr.disp, (XIAnyHierarchyChangeInfo*)&c, 1); + XFlush(e_devicemgr.disp); + XSync(e_devicemgr.disp, False); + + if (ret!=Success) return EINA_FALSE; + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][create_master_device] new master (%s) was created !\n", E_NEW_MASTER_NAME); + + return EINA_TRUE; +} + +static Eina_Bool +_e_devicemgr_remove_master_device(int master_id) +{ + int ret; + XIRemoveMasterInfo r; + + if (master_id < 0) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][remove_master_device] master_id(%d) is invalid !\n", master_id); + return EINA_FALSE; + } + + r.type = XIRemoveMaster; + r.deviceid = master_id; + r.return_mode = XIFloating; + + ret = XIChangeHierarchy(e_devicemgr.disp, (XIAnyHierarchyChangeInfo*)&r, 1); + XFlush(e_devicemgr.disp); + XSync(e_devicemgr.disp, False); + + if (ret!=Success) return EINA_FALSE; + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][remove_master_device] new master (%s) was removed !\n", E_NEW_MASTER_NAME); + + return EINA_TRUE; +} + +static Eina_Bool +_e_devicemgr_detach_slave(int slave_id) +{ + int ret; + XIDetachSlaveInfo detach; + detach.type = XIDetachSlave; + detach.deviceid = slave_id; + + ret = XIChangeHierarchy(e_devicemgr.disp, (XIAnyHierarchyChangeInfo*)&detach, 1); + XFlush(e_devicemgr.disp); + XSync(e_devicemgr.disp, False); + + if (ret!=Success) return EINA_FALSE; + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][detach_slave] slave (id=%d) was removed !\n", slave_id); + + return EINA_TRUE; +} + +static Eina_Bool +_e_devicemgr_reattach_slave(int slave_id, int master_id) +{ + int ret; + XIAttachSlaveInfo attach; + + attach.type = XIAttachSlave; + attach.deviceid = slave_id; + attach.new_master = master_id; + + ret = XIChangeHierarchy(e_devicemgr.disp, (XIAnyHierarchyChangeInfo*)&attach, 1); + XFlush(e_devicemgr.disp); + XSync(e_devicemgr.disp, False); + + if (ret!=Success) return EINA_FALSE; + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][reattach_slave] slave (id=%d) was reattached to master (id:%d) !\n", slave_id, master_id); + + return EINA_TRUE; +} + +static void +_e_devicemgr_show_device_list(unsigned int val) +{ + SLOG(LOG_DEBUG, "DEVICEMGR", "\n[e_devicemgr] - Device List = Start =====================\n"); + + if (e_devicemgr.device_list) + { + Eina_List* l; + DeviceMgr_Device_Info *data; + + EINA_LIST_FOREACH(e_devicemgr.device_list, l, data) + { + if (data) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "Device id : %d Name : %s\n", data->id, data->name); + switch (data->type) + { + case E_DEVICEMGR_HWKEY: + SLOG(LOG_DEBUG, "DEVICEMGR", " : type : H/W Key\n"); + break; + + case E_DEVICEMGR_KEYBOARD: + SLOG(LOG_DEBUG, "DEVICEMGR", " : type : Keyboard\n"); + break; + + case E_DEVICEMGR_MOUSE: + SLOG(LOG_DEBUG, "DEVICEMGR", " : type : Mouse\n"); + break; + + case E_DEVICEMGR_TOUCHSCREEN: + SLOG(LOG_DEBUG, "DEVICEMGR", " : type : Touchscreen (use=%s)\n", (data->use == XIFloatingSlave) ? "FloatingSlave" : "Slave"); + break; + + case E_DEVICEMGR_GAMEPAD: + SLOG(LOG_DEBUG, "DEVICEMGR", " : type : Gamepad\n"); + break; + + default: + SLOG(LOG_DEBUG, "DEVICEMGR", " : type : Unknown\n"); + } + } + } + } + else + { + SLOG(LOG_DEBUG, "DEVICEMGR", "No input devices...\n"); + } + + SLOG(LOG_DEBUG, "DEVICEMGR", "\n[e_devicemgr] - Device List = End =====================\n"); +} + +static Eina_Bool +_e_devicemgr_virtual_touchpad_helper_enable(Eina_Bool is_enable) +{ + Eina_Bool result; + + if (is_enable) + { + if (e_devicemgr.num_zones < 2) return EINA_FALSE; + result = _e_devicemgr_create_master_device(E_NEW_MASTER_NAME); + if (EINA_FALSE==result) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][virtual_touchpad_helper_enable] Failed to create master device ! (name=%s)\n", + E_NEW_MASTER_NAME); + return EINA_FALSE; + } + _e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, _e_devicemgr_get_nth_zone(2), EINA_TRUE, NULL, EINA_TRUE, EINA_FALSE); + } + else + { + result = _e_devicemgr_remove_master_device(e_devicemgr.new_master_pointer_id); + if (EINA_FALSE==result) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][virtual_touchpad_helper_enable] Failed to remove master device ! (id=%d)\n", + e_devicemgr.new_master_pointer_id); + return EINA_FALSE; + } + //_e_devicemgr_set_confine_information(e_devicemgr.virtual_touchpad_id, NULL, EINA_FALSE, NULL, EINA_FALSE); + } + + return EINA_TRUE; +} + +static E_Zone* +_e_devicemgr_get_nth_zone(int index) +{ + Eina_List *l; + E_Zone *zone; + int count = 0; + + if (e_devicemgr.num_zones < index) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][get_nth_zone] %d th zone doesn't exist ! (num_zones=%d)\n", + index, e_devicemgr.num_zones); + return NULL; + } + + EINA_LIST_FOREACH(e_devicemgr.zones, l, zone) + { + if (zone) + { + if (count==(index-1)) return zone; + else count++; + } + } + + return NULL; +} + +static int +_e_devicemgr_get_configuration (void) +{ + if (!e_mod_devicemgr_config_init()) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][get_configuration] Failed @ e_mod_devicemgr_config_init()..!\n"); + return 0; + } + + e_devicemgr.scrnconf_enable = _e_devicemgr_cfg->ScrnConf.enable; + e_devicemgr.default_dispmode = _e_devicemgr_cfg->ScrnConf.default_dispmode; + e_devicemgr.isPopUpEnabled = _e_devicemgr_cfg->ScrnConf.isPopUpEnabled; + + return 1; +} + +static int +_e_devicemgr_update_configuration (void) +{ + e_mod_devicemgr_config_save(); + + return 1; +} + +static void +_e_devicemgr_virtual_multitouch_helper_init(int deviceid) +{ + int i; + + for ( i=0 ; i < MAX_TOUCH ; i++ ) + { + if (e_devicemgr.virtual_multitouch_id[i] < 0) + { + e_devicemgr.virtual_multitouch_id[i] = deviceid; + break; + } + } + + if (i < MAX_TOUCH-1) return; + + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][virtual_multitouch_helper_init] virtual touchscreen device were attached !\n"); + + e_devicemgr.mouse_in_handler = ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, (Ecore_Event_Handler_Cb)_e_devicemgr_cb_mouse_in, NULL); + e_devicemgr.border_move_end_hook = e_border_hook_add(E_BORDER_HOOK_MOVE_END, _e_devicemgr_hook_border_move_end, NULL); + e_devicemgr.border_resize_end_hook = e_border_hook_add(E_BORDER_HOOK_RESIZE_END, _e_devicemgr_hook_border_resize_end, NULL); + + if (!e_devicemgr.mouse_in_handler) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add ECORE_X_EVENT_MOUSE_IN handler\n", __FUNCTION__); + if (!e_devicemgr.border_move_end_hook) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add E_BORDER_HOOK_MOVE_END hook\n", __FUNCTION__); + if (!e_devicemgr.border_resize_end_hook) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][%s] Failed to add E_BORDER_HOOK_RESIZE_END hook\n", __FUNCTION__); +} + +static void +_e_devicemgr_virtual_multitouch_helper_fini(void) +{ + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][virtual_multitouch_helper_init] virtual touchscreen device(s) were removed !\n"); + memset(&e_devicemgr.virtual_multitouch_id, -1, sizeof(e_devicemgr.virtual_multitouch_id)); + + if (e_devicemgr.mouse_in_handler) ecore_event_handler_del(e_devicemgr.mouse_in_handler); + if (e_devicemgr.border_move_end_hook) e_border_hook_del(e_devicemgr.border_move_end_hook); + if (e_devicemgr.border_resize_end_hook) e_border_hook_del(e_devicemgr.border_resize_end_hook); + + e_devicemgr.mouse_in_handler = NULL; + e_devicemgr.border_move_end_hook = NULL; + e_devicemgr.border_resize_end_hook = NULL; +} + +static void +_e_devicemgr_update_input_transform_matrix(Eina_Bool reset) +{ + int i; + + static float identity_matrix[] = { 1.0f, 0, 0, 0, 1.0f, 0, 0, 0, 1.0f }; + + if (0 > e_devicemgr.virtual_multitouch_id[0]) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][update_input_transform_matrix] e_devicemgr.virtual_multitouch_id is invalid !\n"); + return; + } + + for( i = 0 ; i < 3 ; i++ ) + { + if (reset) + XIChangeProperty(e_devicemgr.disp, e_devicemgr.virtual_multitouch_id[i], e_devicemgr.atomInputTransform, + e_devicemgr.atomFloat, 32, PropModeReplace, (unsigned char*)&identity_matrix, 9); + else + XIChangeProperty(e_devicemgr.disp, e_devicemgr.virtual_multitouch_id[i], e_devicemgr.atomInputTransform, + e_devicemgr.atomFloat, 32, PropModeReplace, (unsigned char*)&e_devicemgr.tmatrix[0], 9); + } + + XFlush(e_devicemgr.disp); + XSync(e_devicemgr.disp, False); + + if (reset) SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][update_input_transform_matrix] transform matrix was reset to identity_matrix !\n"); + else SLOG(LOG_DEBUG, "DEVICEMGR", "[e_devicemgr][update_input_transform_matrix] transform matrix was updated !\n"); +} + diff --git a/src/e_mod_main.h b/src/e_mod_main.h new file mode 100644 index 0000000..bd3098f --- /dev/null +++ b/src/e_mod_main.h @@ -0,0 +1,309 @@ +#ifndef __E_MOD_MAIN_H__ +#define __E_MOD_MAIN_H__ + +#include "e.h" +#include "e_randr.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "scrnconf_devicemgr.h" +#include "virt_monitor_devicemgr.h" +#include "hib_devicemgr.h" +#include "e_mod_scrnconf.h" +#include "e_mod_drv.h" + +#ifndef LockMask +#define LockMask (1<<1) +#define Mod2Mask (1<<4) +#endif +#define CapsLockMask LockMask +#define NumLockMask Mod2Mask + +#ifndef ECORE_X_RANDR_1_2 +#define ECORE_X_RANDR_1_2 ((1 << 16) | 2) +#endif +#ifndef ECORE_X_RANDR_1_3 +#define ECORE_X_RANDR_1_3 ((1 << 16) | 3) +#endif + +#ifndef E_RANDR_NO_12 +#define E_RANDR_NO_12 (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12) +#endif + +#ifndef MAX_TOUCH +#define MAX_TOUCH 3 +#endif + +#define INSIDE(x, y, x1, y1, x2, y2) (x1 <= x && x <= x2 && y1 <= y && y <= y2) + +#define E_PROP_DEVICE_LIST "E_DEVICEMGR_DEVICE_LIST" + +#define XI_PROP_DEVICE_ENABLE "Device Enabled" +#define E_PROP_DEVICE_NAME "Device" +#define E_PROP_DEVICEMGR_INPUTWIN "DeviceMgr Input Window" +#define E_PROP_VIRTUAL_TOUCHPAD_INT "Virtual Touchpad Interaction" +#define E_PROP_X_MOUSE_CURSOR_ENABLE "X Mouse Cursor Enable" +#define E_PROP_X_MOUSE_EXIST "X Mouse Exist" +#define E_PROP_X_EXT_KEYBOARD_EXIST "X External Keyboard Exist" +#define E_PROP_HW_KEY_INPUT_STARTED "HW Keyboard Input Started" +#define E_PROP_X_EVDEV_AXIS_LABELS "Axis Labels" +#define E_PROP_X_EVDEV_BUTTON_LABELS "Button Labels" +#define E_PROP_XRROUTPUT "X_RR_PROPERTY_REMOTE_CONTROLLER" +#define E_PROP_VIRTUAL_TOUCHPAD "_X_Virtual_Touchpad_" +#define E_PROP_TOUCH_INPUT "X_TouchInput" +#define E_PROP_VIRTUAL_TOUCHPAD_CONFINE_REGION "Evdev Confine Region" +#define E_NEW_MASTER_NAME "New Master" +#define E_VIRTUAL_TOUCHPAD_NAME "Virtual Touchpad" +#define EVDEVMULTITOUCH_PROP_TRANSFORM "EvdevMultitouch Transform Matrix" +#define XATOM_FLOAT "FLOAT" +#define E_PROP_EXTERNAL_KEYBOARD_ENABLED "External Keyboard Enabled" +#define XI_PROP_REL_MOVE_STATUS "Relative Move Status" +#define XI_PROP_REL_MOVE_ACK "Relative Move Acknowledge" +#define E_PROP_GAMEMODE_ENABLED "Game Mode Enabled" +#define E_PROP_MULTITOUCH_DEVICEID "MultitouchDeviceID" +#define E_PROP_PALM_DISABLING_WIN_RUNNING "Palm Disabling Window Running" +#define GESTURE_PALM_REJECTION_MODE "GESTURE_PALM_REJECTION_MODE" + +#define DEVICEMGR_PREFIX "/usr/lib/enlightenment/modules/e17-extra-modules-devicemgr/" + +#ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_ +#define TOUCH_DEVICE_NAME "Virtual core XTEST touch" +#define LEN_TOUCH_DEVICE_NAME 24 +#define FUNCTION_KEY_DEVICE_NAME "Virtual core XTEST functionkeys" +#define LEN_FUNCTION_KEY_DEVICE_NAME 23 +#endif //_F_SUPPORT_XTEST_TOUCH_EVENT_ + +#define GESTURE_WINDOW_STACK_CHANGED "GESTURE_WINDOW_STACK_CHANGED" + +typedef enum _VirtualTouchpad_MsgType +{ + E_VIRTUAL_TOUCHPAD_NEED_TO_INIT, + E_VIRTUAL_TOUCHPAD_DO_INIT, + E_VIRTUAL_TOUCHPAD_AREA_INFO, + E_VIRTUAL_TOUCHPAD_POINTED_WINDOW, + E_VIRTUAL_TOUCHPAD_WINDOW, + E_VIRTUAL_TOUCHPAD_MT_BEGIN, + E_VIRTUAL_TOUCHPAD_MT_END, + E_VIRTUAL_TOUCHPAD_MT_MATRIX_SET_DONE, + E_VIRTUAL_TOUCHPAD_CONFINE_SET, + E_VIRTUAL_TOUCHPAD_CONFINE_UNSET, + E_VIRTUAL_TOUCHPAD_SHUTDOWN +} VirtualTouchpad_MsgType; + +typedef enum +{ + E_DEVICEMGR_HWKEY= 1, + E_DEVICEMGR_KEYBOARD, + E_DEVICEMGR_MOUSE, + E_DEVICEMGR_TOUCHSCREEN, + E_DEVICEMGR_GAMEPAD +} DeviceMgrDeviceType; + +typedef struct _DeviceMgr_Device_Info DeviceMgr_Device_Info; + +struct _DeviceMgr_Device_Info +{ + int id; + const char *name; + DeviceMgrDeviceType type; + int master_id; + int use; +}; + +typedef struct _DeviceMgr_ +{ + Ecore_X_Display* disp; + Ecore_X_Window rootWin; + Ecore_X_Window input_window; + int num_zones; + Eina_List *zones; + + /* scrn conf configuration */ + Eina_Bool scrnconf_enable; + Utilx_Scrnconf_Dispmode default_dispmode; + Eina_Bool isPopUpEnabled; + + Eina_Bool xkb_available; + + /* scrn conf preferred size */ + int hdmi_preferred_w; + int hdmi_preferred_h; + int virtual_preferred_w; + int virtual_preferred_h; + + Ecore_X_Atom atomDeviceEnabled; + Ecore_X_Atom atomRROutput; + Ecore_X_Atom atomAxisLabels; + Ecore_X_Atom atomButtonLabels; + Ecore_X_Atom atomXMouseExist; + Ecore_X_Atom atomXMouseCursorEnable; + Ecore_X_Atom atomXExtKeyboardExist; + Ecore_X_Atom atomHWKbdInputStarted; + Ecore_X_Atom atomDeviceList; + Ecore_X_Atom atomDeviceName; + Ecore_X_Atom atomVirtualTouchpadConfineRegion; + Ecore_X_Atom atomVirtualTouchpad; + Ecore_X_Atom atomTouchInput; + Ecore_X_Atom atomInputTransform; + Ecore_X_Atom atomFloat; + Ecore_X_Atom atomVirtualTouchpadInt; + Ecore_X_Atom atomDeviceMgrInputWindow; + Ecore_X_Atom atomExKeyboardEnabled; + Ecore_X_Atom atomRelativeMoveStatus; + Ecore_X_Atom atomRelativeMoveAck; + Ecore_X_Atom atomGameModeEnabled; + Ecore_X_Atom atomMultitouchDeviceId; + + Ecore_X_Atom atomPalmDisablingWinRunning; + Ecore_X_Window palmDisablingWin; + Ecore_X_Atom atomPalmRejectionMode; + + /* scrn conf atoms */ + Ecore_X_Atom atomScrnConfDispModeSet; + Ecore_X_Atom atomVirtMonReq; + Ecore_X_Atom atomHibReq; + + /* devicemgr config atom */ + Ecore_X_Atom atomDevMgrCfg; + + /* Notify to gesture driver about window stack change */ + Ecore_X_Atom atomWindowStackisChanged; + + int num_touchscreen_devices; + int num_pointer_devices; + int num_keyboard_devices; + int num_hwkey_devices; + Eina_List *device_list; + + Ecore_Event_Handler *window_property_handler; + Ecore_Event_Handler *event_generic_handler; + Ecore_Event_Handler *zone_add_handler; + Ecore_Event_Handler *zone_del_handler; + Ecore_Event_Handler *mouse_in_handler; + Ecore_Event_Handler *randr_crtc_handler; + Ecore_Event_Handler *randr_output_handler; + Ecore_Event_Handler *randr_output_property_handler; + Ecore_Event_Handler *client_message_handler; + Ecore_Event_Handler *window_destroy_handler; + E_Border_Hook *border_move_end_hook; + E_Border_Hook *border_resize_end_hook; + E_Msg_Handler *e_msg_handler; + + //variables to set XRROutputProperty + RROutput output; + char rroutput_buf[256]; + int rroutput_buf_len; + + /* selection */ + Ecore_X_Atom selection_atom; + Ecore_X_Atom selection_type_atom; + Eina_Bool selection_ownership; + Ecore_X_Window selection_xwin; + Ecore_X_Randr_Output selection_output_xid; + char selection_prev_owner[256]; + Ecore_Event_Handler *selection_clear_handler; + Ecore_Event_Handler *selection_request_handler; + Ecore_Event_Handler *selection_notify_handler; + Ecore_Timer *selection_request_timeout; + + //variables related to XI2 + int xi2_opcode; + XIEventMask eventmask; + + //XIMasterPointer id(s) + int vcp_id; + int vck_id; + int vcp_xtest_pointer_id; + int vck_xtest_keyboard_id; + int new_master_pointer_id; + unsigned int cursor_show; + int cursor_show_ack; + int rel_move_deviceid; + + int virtual_touchpad_id; + int virtual_multitouch_id[MAX_TOUCH]; + int virtual_touchpad_area_info[4]; + int virtual_touchpad_pointed_window_info[4]; + int virtual_multitouch_done; + int virtual_touchpad_cursor_pos[2]; + + Ecore_X_Window virtual_touchpad_window; + Ecore_X_Window virtual_touchpad_pointed_window; + + int gamepad_id; + int gesture_id; + Eina_Bool palm_disabled; + + //input transform matrix + float tmatrix[9]; +} DeviceMgr; + +EAPI extern E_Module_Api e_modapi; + +EAPI void* e_modapi_init (E_Module* m); +EAPI int e_modapi_shutdown (E_Module* m); +EAPI int e_modapi_save (E_Module* m); + +static int _e_devicemgr_init(void); +static void _e_devicemgr_fini(void); + +static int _e_devicemgr_xinput_init(void); + +static int _e_devicemgr_cb_window_property(void *data, int ev_type, void *ev); +static int _e_devicemgr_cb_window_destroy(void *data, int ev_type, void *ev); +static int _e_devicemgr_cb_event_generic(void *data, int ev_type, void *event); +static int _e_devicemgr_cb_zone_add(void *data, int ev_type, void *event); +static int _e_devicemgr_cb_zone_del(void *data, int ev_type, void *event); +static Eina_Bool _e_devicemgr_cb_mouse_in(void *data, int type, void *event); +static void _e_devicemgr_hook_border_move_end(void *data, void *border); +static void _e_devicemgr_hook_border_resize_end(void *data, void *border); +static Eina_Bool _e_devicemgr_get_zones(void); +static E_Zone* _e_devicemgr_get_nth_zone(int index); +static void _e_mod_move_e_msg_handler(void *data, const char *name, const char *info, int val, E_Object *obj, void *msgdata); + +static void _e_devicemgr_update_input_transform_matrix(Eina_Bool reset); +static void _e_devicemgr_init_transform_matrix(void); +static void _e_devicemgr_init_output(void); +static void _e_devicemgr_init_input(void); +static int _e_devicemgr_marshalize_string (char* buf, int num, char* srcs[]); + +static int _e_devicemgr_check_device_type(int deviceid, DeviceMgrDeviceType type, const char* devname); +static void _e_devicemgr_xi2_device_property_handler(XIPropertyEvent *event); +static void _e_devicemgr_xi2_device_changed_handler(XIDeviceChangedEvent *event); +static void _e_devicemgr_xi2_device_hierarchy_handler(XIHierarchyEvent *event); +static void _e_devicemgr_device_enabled(int id, int type); +static void _e_devicemgr_device_disabled(int id, int type); +static void _e_devicemgr_master_pointer_added(int id); +static void _e_devicemgr_master_pointer_removed(int id); +static void _e_devicemgr_slave_switched(int deviceid, int sourceid); +static void _e_devicemgr_device_changed(int deviceid, int sourceid); +static void _e_devicemgr_enable_mouse_cursor(unsigned int val); +static void _e_devicemgr_set_confine_information(int deviceid, E_Zone *zone, Eina_Bool isset, int region[4], Eina_Bool pointer_warp, Eina_Bool confine); +static void _e_devicemgr_set_mouse_exist(unsigned int val, int propset); +static void _e_devicemgr_set_keyboard_exist(unsigned int val, int is_connected); +static void _e_devicemgr_append_prop_touchscreen_device_id(int id); +static void _e_devicemgr_remove_prop_touchscreen_device_id(int id); + +static int _e_devicemgr_xkb_init(void); +static int _e_devicemgr_get_lockmodifier_mask(void); +static int _e_devicemgr_xkb_set_on(unsigned int mask); +static int _e_devicemgr_lockmodifier_set(void); + +static Eina_Bool _e_devicemgr_create_master_device(char* master_name); +static Eina_Bool _e_devicemgr_remove_master_device(int master_id); +static Eina_Bool _e_devicemgr_detach_slave(int slave_id); +static Eina_Bool _e_devicemgr_reattach_slave(int slave_id, int master_id); +static Eina_Bool _e_devicemgr_virtual_touchpad_helper_enable(Eina_Bool is_enable); +static void _e_devicemgr_virtual_multitouch_helper_init(int deviceid); +static void _e_devicemgr_virtual_multitouch_helper_fini(void); +static void _e_devicemgr_show_device_list(unsigned int val); + +Eina_Bool e_mod_sf_rotation_init(void); +Eina_Bool e_mod_sf_rotation_deinit(void); +#endif//__E_MOD_MAIN_H__ diff --git a/src/e_mod_scrnconf.c b/src/e_mod_scrnconf.c new file mode 100755 index 0000000..fe81ee9 --- /dev/null +++ b/src/e_mod_scrnconf.c @@ -0,0 +1,1036 @@ +#include "e.h" +#include "e_randr.h" +#include "e_mod_main.h" +#include "e_mod_scrnconf.h" +#include "scrnconf_devicemgr.h" + +#ifdef _MAKE_ATOM +# undef _MAKE_ATOM +#endif + +#define _MAKE_ATOM(a, s) \ + do { \ + a = ecore_x_atom_get (s); \ + if (!a) \ + SLOG(LOG_DEBUG, "DEVICEMGR", \ + "[E-devmgr] ##s creation failed.\n"); \ + } while (0) + +#define STR_XRR_DISPLAY_MODE_PROPERTY "XRR_PROPERTY_DISPLAY_MODE" + +/* display mode */ +typedef enum +{ + XRR_OUTPUT_DISPLAY_MODE_NULL, /* null */ + XRR_OUTPUT_DISPLAY_MODE_WB_CLONE, /* write-back */ +} XRROutputPropDisplayMode; + +/* screen conf dialog */ +static E_Dialog *g_dia = NULL; + +/* screen configuration info */ +static struct +{ + SC_EXT_OUTPUT sc_output; + Utilx_Scrnconf_Dispmode sc_dispmode; + Utilx_Scrnconf_Status sc_stat; + SC_EXT_RES sc_res; +} sc_ext = +{ + SC_EXT_OUTPUT_NULL, + UTILX_SCRNCONF_DISPMODE_NULL, + UTILX_SCRNCONF_STATUS_NULL, + SC_EXT_RES_NULL, +}; + +/* mode info */ +static struct +{ + int sc_res; + double refresh; + Ecore_X_Randr_Mode_Info * mode_info; +} sc_ext_mode [] = +{ + {SC_EXT_RES_1920X1080, 0.0, NULL}, + {SC_EXT_RES_1280X720, 0.0, NULL}, + {SC_EXT_RES_720X480, 0.0, NULL}, + {SC_EXT_RES_720X576, 0.0, NULL}, +}; + +static char *str_output[3] = { + "null", + "HDMI1", + "Virtual1", +}; + +static char *str_dispmode[3] = { + "null", + "CLONE", + "EXTENDED", +}; + +static char *str_stat[3] = { + "null", + "CONNECT", + "ACTIVE", +}; + +static char *str_resolution[5] = { + "null", + "1920x1080", + "1280x720", + "720x480", + "720x576", +}; + +/* Calculates the vertical refresh rate of a mode. */ +static double +_cal_vrefresh(Ecore_X_Randr_Mode_Info *mode_info) +{ + double refresh = 0.0; + double dots = mode_info->hTotal * mode_info->vTotal; + if (!dots) + return 0; + refresh = (mode_info->dotClock + dots/2) / dots; + + if (refresh > 0xffff) + refresh = 0xffff; + + return refresh; +} + +static char * +_get_str_output(int output) +{ + char *str = NULL; + + switch (output) + { + case SC_EXT_OUTPUT_HDMI: + str = str_output[1]; + break; + case SC_EXT_OUTPUT_VIRTUAL: + str = str_output[2]; + break; + default: + str = str_output[0]; + break; + } + + return str; +} + +static char * +_get_str_dispmode(int dispmode) +{ + char *str = NULL; + + switch (dispmode) + { + case UTILX_SCRNCONF_DISPMODE_CLONE: + str = str_dispmode[1]; + break; + case UTILX_SCRNCONF_DISPMODE_EXTENDED: + str = str_dispmode[2]; + break; + default: + str = str_dispmode[0]; + break; + } + + return str; +} +static char * +_get_str_stat(int stat) +{ + char *str = NULL; + + switch (stat) + { + case UTILX_SCRNCONF_STATUS_CONNECT: + str = str_stat[1]; + break; + case UTILX_SCRNCONF_STATUS_ACTIVE: + str = str_stat[2]; + break; + case UTILX_SCRNCONF_STATUS_NULL: + str = str_stat[0]; + break; + default: + str = str_stat[0]; + break; + } + + return str; +} + +static char * +_get_str_resolution(int resolution) +{ + char *str = NULL; + + switch (resolution) + { + case SC_EXT_RES_1920X1080: + str = str_resolution[1]; + break; + case SC_EXT_RES_1280X720: + str = str_resolution[2]; + break; + case SC_EXT_RES_720X480: + str = str_resolution[3]; + break; + case SC_EXT_RES_720X576: + str = str_resolution[4]; + break; + default: + str = str_resolution[0]; + break; + } + + return str; +} + +static int +_get_resolution_str (char *res_name) +{ + int resolution = SC_EXT_RES_NULL; + + if (!strcmp (res_name, str_resolution[1])) + resolution = SC_EXT_RES_1920X1080; + else if (!strcmp (res_name, str_resolution[2])) + resolution = SC_EXT_RES_1280X720; + else if (!strcmp (res_name, str_resolution[3])) + resolution = SC_EXT_RES_720X480; + else if (!strcmp (res_name, str_resolution[4])) + resolution = SC_EXT_RES_720X576; + else + resolution = SC_EXT_RES_NULL; + + return resolution; +} + + +#if SCRN_CONF_DEBUG +static void +_debug_possible_crtc (E_Randr_Output_Info *output_info) +{ + E_Randr_Crtc_Info *crtc_info = NULL; + E_Randr_Output_Info *t_o = NULL; + Ecore_X_Randr_Mode_Info *t_m = NULL; + Eina_List *t_l, *l_crtc; + + EINA_LIST_FOREACH (output_info->possible_crtcs, l_crtc, crtc_info) + { + if (crtc_info == NULL) + continue; + + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: possible crtc = %d\n", crtc_info->xid); + + EINA_LIST_FOREACH (crtc_info->outputs, t_l, t_o) + { + SLOG(LOG_DEBUG, "DEVICEMGR", " output : %s\n", t_o->name); + } + + EINA_LIST_FOREACH (crtc_info->possible_outputs, t_l, t_o) + { + SLOG(LOG_DEBUG, "DEVICEMGR", " possible output : %s\n", t_o->name); + } + + EINA_LIST_FOREACH (crtc_info->outputs_common_modes, t_l, t_m) + { + if (!t_m->name) + break; + SLOG(LOG_DEBUG, "DEVICEMGR", " outputs common modes : %s\n", t_m->name); + } + + if (!crtc_info->current_mode) + { + SLOG(LOG_DEBUG, "DEVICEMGR", " no current mode \n"); + crtc_xid = crtc_info->xid; + SLOG(LOG_DEBUG, "DEVICEMGR", " crtc_id : %d\n", crtc_info->xid); + } + else + { + SLOG(LOG_DEBUG, "DEVICEMGR", " current set mode : %s\n", crtc_info->current_mode->name); + SLOG(LOG_DEBUG, "DEVICEMGR", " crtc_id : %d\n", crtc_info->xid); + } + } +} +#endif + +static E_Randr_Output_Info * +_scrnconf_external_get_output_info_from_output_xid (Ecore_X_Randr_Output output_xid) +{ + E_Randr_Output_Info *output_info = NULL; + Eina_List *iter; + + EINA_LIST_FOREACH (e_randr_screen_info.rrvd_info.randr_info_12->outputs, iter, output_info) + { + if (output_info == NULL) + continue; + + if (output_info->xid == output_xid) + return output_info; + } + + return NULL; +} + +static E_Randr_Output_Info * +_scrnconf_external_get_output_info_from_output (int output) +{ + E_Randr_Output_Info *output_info = NULL; + Eina_List *iter; + + EINA_LIST_FOREACH (e_randr_screen_info.rrvd_info.randr_info_12->outputs, iter, output_info) + { + if (output_info == NULL) + continue; + + if (!strcmp(output_info->name, _get_str_output(output))) + return output_info; + } + + return NULL; +} + +static int +_scrnconf_external_get_output (E_Randr_Output_Info *output_info) +{ + int output = SC_EXT_OUTPUT_NULL; + + if (!strcmp (output_info->name, "HDMI1")) + output = SC_EXT_OUTPUT_HDMI; + else if (!strcmp (output_info->name, "Virtual1")) + output = SC_EXT_OUTPUT_VIRTUAL; + else + output = SC_EXT_OUTPUT_NULL; + + return output; +} + +static int +_scrnconf_external_set_modes (int sc_output, int num_res, int *resolutions) +{ + E_Randr_Output_Info *output_info = NULL; + Ecore_X_Randr_Mode_Info *mode_info = NULL; + Eina_List *l_mode; + int res = SC_EXT_RES_NULL; + double refresh = 0.0; + int i; + + output_info = _scrnconf_external_get_output_info_from_output (sc_output); + if (!output_info) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to find output_info from sc_output\n"); + return 0; + } + + EINA_LIST_FOREACH (output_info->monitor->modes, l_mode, mode_info) + { + if (mode_info == NULL) + continue; + +#if 0 //debug + SLOG(LOG_DEBUG, "DEVICEMGR", "%s(%d): mode_info->name, %s, vrefresh, %f\n" + , __func__, __LINE__, mode_info->name, _cal_vrefresh(mode_info)); +#endif + res = _get_resolution_str (mode_info->name); + if (res == SC_EXT_RES_NULL) + continue; + + for (i = 0; i < num_res; i++) + { + if (sc_ext_mode[i].sc_res == res) + { + refresh = _cal_vrefresh (mode_info); + if (refresh > sc_ext_mode[i].refresh) + { + sc_ext_mode[i].refresh = refresh; + sc_ext_mode[i].mode_info = mode_info; + } + } + } + } + + for (i = 0; i < num_res; i++) + { + resolutions[i] = sc_ext_mode[i].sc_res; + } + +#if 0 // debug + for (i = 0; i < num_res; i++) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: res info:: (%d): %s, %f, %p\n" + , i, _get_str_resolution(sc_ext_mode[i].sc_res), sc_ext_mode[i].refresh, sc_ext_mode[i].mode_info); + + } +#endif + + return 1; +} + +static int +_scrnconf_external_get_setting_info (int output, int resolution, Ecore_X_Randr_Output *output_xid, + Ecore_X_Randr_Crtc *crtc_xid, Ecore_X_Randr_Mode *mode_xid, int *output_w, int *output_h) +{ + E_Randr_Output_Info *output_info = NULL; + E_Randr_Crtc_Info *crtc_info = NULL; + Ecore_X_Randr_Mode_Info *mode_info = NULL; + Eina_List *l_crtc; + Eina_Bool found_output = EINA_FALSE; + int num_res = 0; + int i; + + output_info = _scrnconf_external_get_output_info_from_output (output); + if (output_info == NULL) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: fail to get output_info from sc_output\n"); + goto finish; + } + + output_xid[0] = output_info->xid; + + num_res = sizeof (sc_ext_mode) / sizeof (sc_ext_mode[0]); + + /* find mode info */ + for (i = 0; i < num_res; i++) + { + if (sc_ext_mode[i].sc_res == resolution) + { + mode_info = sc_ext_mode[i].mode_info; + break; + } + } + + if (mode_info == NULL) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: fail to get mode_info from sc_output\n"); + goto finish; + } + + *output_w = mode_info->width; + *output_h = mode_info->height; + *mode_xid = mode_info->xid; + found_output = EINA_TRUE; + +#if SCRN_CONF_DEBUG + _debug_possible_crtc (output_info); +#endif + + EINA_LIST_FOREACH (output_info->possible_crtcs, l_crtc, crtc_info) + { + if (crtc_info == NULL) + continue; + + if (!crtc_info->current_mode) + { + *crtc_xid = crtc_info->xid; + } + } + + if (output_info->crtc && (!*crtc_xid)) + *crtc_xid = output_info->crtc->xid; + else + *crtc_xid = 0; + +finish: + + return found_output; +} + +static int +_scrnconf_external_set_extended (int output, int resolution) +{ + E_Randr_Output_Info *output_info = NULL; + Eina_List *l_output; + int lvds_x = 0, lvds_y = 0, lvds_w = 0, lvds_h = 0; + int output_x = 0, output_y = 0, output_w = 0, output_h = 0; + int resize_w = 0, resize_h = 0; + Ecore_X_Randr_Crtc crtc_xid = 0; + Ecore_X_Randr_Output output_xid[1] = {0}; + Ecore_X_Randr_Mode mode_xid = 0; + + /* get lvds information */ + EINA_LIST_FOREACH (e_randr_screen_info.rrvd_info.randr_info_12->outputs, l_output, output_info) + { + + if (output_info == NULL) + continue; + + if (!strcmp (output_info->name, "LVDS1")) + { + lvds_x = output_info->crtc->geometry.x; + lvds_y = output_info->crtc->geometry.y; + lvds_w = output_info->crtc->current_mode->width; + lvds_h = output_info->crtc->current_mode->height; + break; + } + } + + if (!_scrnconf_external_get_setting_info (output, resolution, output_xid, &crtc_xid, &mode_xid, &output_w, &output_h)) + goto set_fail; + + if (crtc_xid == 0) + goto set_fail; + + /* set the output is right-of lvds output */ + output_x = lvds_w; + output_y = 0; + resize_w = lvds_w + output_w; + + if (lvds_h > output_h) + resize_h = lvds_h; + else + resize_h = output_h; + + ecore_x_grab (); + + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: set screen resize (%d,%d)\n", resize_w, resize_h); + if (!ecore_x_randr_screen_current_size_set (e_randr_screen_info.root, resize_w, resize_h, 0, 0)) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: fail to resize the screen\n"); + goto set_fail; + } + + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: set crtc_id, %d output_id, %d mode_id, %d)!\n", crtc_xid, output_xid[0], mode_xid); + if (!ecore_x_randr_crtc_settings_set (e_randr_screen_info.root, crtc_xid, output_xid, 1, output_x, + output_y, mode_xid, ECORE_X_RANDR_ORIENTATION_ROT_0)) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: fail to set x=%d, y=%d, w=%d, h=%d mode_id=%d, crtc_id=%d\n", + output_x, output_y, output_w, output_h, mode_xid, crtc_xid); + goto set_fail; + } + + e_mod_scrnconf_container_bg_canvas_visible_set(EINA_TRUE); + + ecore_x_ungrab (); + + return 1; + +set_fail: + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: %s fail to set the extended mode\n", _get_str_output(output)); + ecore_x_ungrab (); + + return 0; +} + +static int +_scrnconf_external_set_clone (int output, int resolution) +{ + E_Randr_Output_Info *output_info = NULL; + Eina_List *l_output; + int output_w = 0, output_h = 0; + int lvds_x = 0, lvds_y = 0, lvds_w = 0, lvds_h = 0; + int resize_w = 0, resize_h = 0; + Ecore_X_Randr_Crtc crtc_xid = 0; + Ecore_X_Randr_Output output_xid[1] = {0}; + Ecore_X_Randr_Mode mode_xid = 0; + Ecore_X_Atom dispmode; + int value[2]; + + /* get lvds information */ + EINA_LIST_FOREACH (e_randr_screen_info.rrvd_info.randr_info_12->outputs, l_output, output_info) + { + + if (output_info == NULL) + continue; + + if (!strcmp (output_info->name, "LVDS1")) + { + lvds_x = output_info->crtc->geometry.x; + lvds_y = output_info->crtc->geometry.y; + lvds_w = output_info->crtc->current_mode->width; + lvds_h = output_info->crtc->current_mode->height; + break; + } + } + + resize_w = lvds_w; + resize_h = lvds_h; + + if (!_scrnconf_external_get_setting_info (output, resolution, output_xid, &crtc_xid, &mode_xid, &output_w, &output_h)) + goto set_fail; + + ecore_x_grab (); + + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: set screen resize (%d,%d)\n", resize_w, resize_h); + if (!ecore_x_randr_screen_current_size_set (e_randr_screen_info.root, resize_w, resize_h, 0, 0)) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: fail to resize the screen\n"); + goto set_fail; + } + + _MAKE_ATOM (dispmode, STR_XRR_DISPLAY_MODE_PROPERTY); + + value[0] = XRR_OUTPUT_DISPLAY_MODE_WB_CLONE; + value[1] = mode_xid; + + /* no ecore x API for XRRChangeOutputProperty */ + XRRChangeOutputProperty (ecore_x_display_get (), output_xid[0], dispmode, XA_INTEGER, 32, + PropModeReplace, (unsigned char *)&value, 2); + + e_mod_scrnconf_container_bg_canvas_visible_set(EINA_FALSE); + + ecore_x_sync (); + + ecore_x_ungrab (); + + return 1; + +set_fail: + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr]: %s fail to set the clone mode\n", _get_str_output(output)); + ecore_x_ungrab (); + + return 0; +} + +static void +_dialog_extended_btn_cb (void *data, E_Dialog *g_dia) +{ + E_Randr_Output_Info *output_info = (E_Randr_Output_Info *)data; + int sc_output = SC_EXT_OUTPUT_NULL; + int sc_res = SC_EXT_RES_NULL; + int num_res = 0; + int *resolutions = NULL; + + sc_output = _scrnconf_external_get_output (output_info); + if (sc_output == SC_EXT_OUTPUT_NULL) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to find sc_output from output_info\n"); + goto set_fail; + } + + num_res = sizeof (sc_ext_mode) / sizeof (sc_ext_mode[0]); + + resolutions = calloc (num_res, sizeof (int)); + if (!resolutions) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to allocate resolutions\n"); + goto set_fail; + } + + if (!_scrnconf_external_set_modes (sc_output, num_res, resolutions)) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to set modes\n"); + goto set_fail; + } + + sc_res = resolutions[0]; + + if (!_scrnconf_external_set_extended (sc_output, sc_res)) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to set modes\n"); + goto set_fail; + } + + /* set display mode */ + sc_ext.sc_dispmode = UTILX_SCRNCONF_DISPMODE_EXTENDED; + + e_mod_scrnconf_external_send_current_status (); + + if (resolutions) + free (resolutions); + + /* destroy dialog */ + e_mod_scrnconf_external_dialog_free (); + return; + +set_fail: + if (resolutions) + free (resolutions); + + /* destroy dialog */ + e_mod_scrnconf_external_dialog_free (); +} + +static void +_dialog_clone_btn_cb (void *data, E_Dialog *g_dia) +{ + E_Randr_Output_Info *output_info = (E_Randr_Output_Info *)data; + int sc_output = SC_EXT_OUTPUT_NULL; + int sc_res = SC_EXT_RES_NULL; + int num_res = 0; + int *resolutions = NULL; + + sc_output = _scrnconf_external_get_output (output_info); + if (sc_output == SC_EXT_OUTPUT_NULL) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to find sc_output from output_info\n"); + goto set_fail; + } + + num_res = sizeof (sc_ext_mode) / sizeof (sc_ext_mode[0]); + + resolutions = calloc (num_res, sizeof (int)); + if (!resolutions) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to allocate resolutions\n"); + goto set_fail; + } + + if (!_scrnconf_external_set_modes (sc_output, num_res, resolutions)) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to set modes\n"); + goto set_fail; + } + + sc_res = resolutions[0]; + + if (!_scrnconf_external_set_clone (sc_output, sc_res)) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to set clone\n"); + goto set_fail; + } + + /* set display mode */ + sc_ext.sc_dispmode = UTILX_SCRNCONF_DISPMODE_EXTENDED; + + e_mod_scrnconf_external_send_current_status (); + + if (resolutions) + free (resolutions); + + /* destroy dialog */ + e_mod_scrnconf_external_dialog_free (); + return; + +set_fail: + if (resolutions) + free (resolutions); + + /* destroy dialog */ + e_mod_scrnconf_external_dialog_free (); +} + +static void +_dialog_cancle_btn_cb (void *data, E_Dialog *g_dia) +{ + /* destroy dialog */ + e_mod_scrnconf_external_dialog_free (); +} + +void +e_mod_scrnconf_external_init () +{ + /* init scrn conf get property */ + scrnconf_ext_update_get_perperty(ecore_x_display_get (), "null", "null", "null", "null"); +} + +void +e_mod_scrnconf_external_deinit () +{} + + +void +e_mod_scrnconf_external_dialog_new (int output) +{ + E_Manager *man; + E_Container *con; + E_Randr_Output_Info *output_info = NULL; + + if (output == SC_EXT_OUTPUT_NULL) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : Unknown output is not supported \n"); + return; + } + + output_info = _scrnconf_external_get_output_info_from_output (output); + if (!output_info) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to get output from xid\n"); + return; + } + + /* set to be null, if dialog already exists */ + if (g_dia != NULL) + e_mod_scrnconf_external_dialog_free (); + + man = e_manager_current_get (); + con = e_container_current_get (man); + + if (output == SC_EXT_OUTPUT_HDMI) + { + g_dia = e_dialog_new (con, "E", "hdmi mode"); + e_dialog_title_set (g_dia, "\nHDMI Connected !!\n"); + e_dialog_text_set (g_dia, "HDMI Connected
Select the screen configuration mode
"); + } + else if (output == SC_EXT_OUTPUT_VIRTUAL) + { + g_dia = e_dialog_new (con, "E", "virtual mode"); + e_dialog_title_set (g_dia, "\nVirtual Connected !!\n"); + e_dialog_text_set (g_dia, "Virtual Connected
Select the screen configuration mode
"); + } + + e_dialog_button_add (g_dia, "CLONE", NULL, _dialog_clone_btn_cb, (void *)output_info); + e_dialog_button_add (g_dia, "EXTENDED", NULL, _dialog_extended_btn_cb, (void *)output_info); + e_dialog_button_add (g_dia, "CANCLE", NULL, _dialog_cancle_btn_cb, (void *)output_info); + + e_dialog_resizable_set (g_dia, 1); + e_win_centered_set (g_dia->win, 1); + e_dialog_show (g_dia); + + ecore_x_sync (); +} + +void +e_mod_scrnconf_external_dialog_free () +{ + if (g_dia != NULL) + { + e_util_defer_object_del (E_OBJECT (g_dia)); + g_dia = NULL; + } + + ecore_x_sync (); +} + +int +e_mod_scrnconf_external_get_output_from_xid (Ecore_X_Randr_Output output_xid) +{ + E_Randr_Output_Info *output_info = NULL; + int output = SC_EXT_OUTPUT_NULL; + + output_info = _scrnconf_external_get_output_info_from_output_xid (output_xid); + if (!output_info) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to get output from xid\n"); + return SC_EXT_OUTPUT_NULL; + } + + output = _scrnconf_external_get_output (output_info); + if (output == SC_EXT_OUTPUT_NULL) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : Unknown output is not supported \n"); + return SC_EXT_OUTPUT_NULL; + } + + return output; +} + +int +e_mod_scrnconf_external_get_default_res (int sc_output, int preferred_w, int preferred_h) +{ + int sc_res = SC_EXT_RES_NULL; + int num_res = 0; + int *resolutions = NULL; + Ecore_X_Randr_Mode_Info * mode_info = NULL; + int i; + + if (sc_output == SC_EXT_OUTPUT_NULL) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : sc_output is unknown\n"); + return 0; + } + + num_res = sizeof (sc_ext_mode) / sizeof (sc_ext_mode[0]); + + resolutions = calloc (num_res, sizeof (int)); + if (!resolutions) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to allocate resolutions\n"); + goto get_fail; + } + + if (!_scrnconf_external_set_modes (sc_output, num_res, resolutions)) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to set modes\n"); + goto get_fail; + } + + /* find the preferred resolution of the virtual output */ + if (preferred_w > 0 && preferred_h > 0) + { + for (i = 0; i < num_res; i++) + { + mode_info = sc_ext_mode[i].mode_info; + + if (!mode_info) + continue; + + if (sc_ext_mode[i].mode_info->width == preferred_w && + sc_ext_mode[i].mode_info->height == preferred_h) + { + sc_res = sc_ext_mode[i].sc_res; + break; + } + } + } + else + { + for (i = 0; i < num_res; i++) + { + mode_info = sc_ext_mode[i].mode_info; + + if (!mode_info) + continue; + + sc_res = sc_ext_mode[i].sc_res; + break; + } + } + + free (resolutions); + + if (sc_res == SC_EXT_RES_NULL) + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : default resolution is NULL\n"); + + + if (sc_output == SC_EXT_OUTPUT_VIRTUAL) + sc_res = SC_EXT_RES_1280X720; + + return sc_res; + +get_fail: + if (resolutions) + free (resolutions); + + return SC_EXT_RES_NULL; +} + +int +e_mod_scrnconf_external_get_output (void) +{ + return sc_ext.sc_output; +} + +int +e_mod_scrnconf_external_set_output (int sc_output) +{ + sc_ext.sc_output = sc_output; + + return 1; +} + +int +e_mod_scrnconf_external_get_res (void) +{ + return sc_ext.sc_res; +} + +int +e_mod_scrnconf_external_set_res (int sc_res) +{ + sc_ext.sc_res = sc_res; + + return 1; +} + +int +e_mod_scrnconf_external_get_status (void) +{ + return sc_ext.sc_stat; +} + +int +e_mod_scrnconf_external_set_status (int sc_stat) +{ + sc_ext.sc_stat = sc_stat; + + return 1; +} + +int +e_mod_scrnconf_external_set_dispmode (int sc_output, int sc_dispmode, int sc_res) +{ + /* set display mode */ + switch (sc_dispmode) + { + case UTILX_SCRNCONF_DISPMODE_CLONE: + if (!_scrnconf_external_set_clone (sc_output, sc_res)) + goto set_fail; + sc_ext.sc_dispmode = UTILX_SCRNCONF_DISPMODE_CLONE; + break; + case UTILX_SCRNCONF_DISPMODE_EXTENDED: + if (!_scrnconf_external_set_extended (sc_output, sc_res)) + goto set_fail; + sc_ext.sc_dispmode = UTILX_SCRNCONF_DISPMODE_EXTENDED; + break; + default: + break; + } + + return 1; + +set_fail: + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to set display mode (%d)\n", sc_dispmode); + return 0; +} + +int +e_mod_scrnconf_external_get_dispmode (void) +{ + return sc_ext.sc_dispmode; +} + +int +e_mod_scrnconf_external_send_current_status (void) +{ + char * str_output = _get_str_output (sc_ext.sc_output); + char * str_stat = _get_str_stat (sc_ext.sc_stat); + char * str_res = _get_str_resolution (sc_ext.sc_res); + char * str_dispmode = _get_str_dispmode (sc_ext.sc_dispmode); + + if (!scrnconf_ext_update_get_perperty(ecore_x_display_get (), str_output, str_stat, str_res, str_dispmode)) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to update get property \n"); + return 0; + } + + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : SEND CLIENT MESSAGES..(%s,%s,%s,%s) \n", str_output, str_stat, str_res, str_dispmode); + + if (!scrnconf_ext_send_status (ecore_x_display_get (), sc_ext.sc_stat, sc_ext.sc_dispmode)) + { + SLOG(LOG_DEBUG, "DEVICEMGR", "[DeviceMgr] : fail to send current status \n"); + return 0; + } + + return 1; +} + +int +e_mod_scrnconf_external_reset (int sc_output) +{ + int i; + int num_res = 0; + + if (sc_output != sc_ext.sc_output || + sc_ext.sc_output == SC_EXT_OUTPUT_NULL) + return 1; + + /* reset scrn conf of a external monitor */ + sc_ext.sc_output = SC_EXT_OUTPUT_NULL; + sc_ext.sc_dispmode = UTILX_SCRNCONF_DISPMODE_NULL; + sc_ext.sc_stat = UTILX_SCRNCONF_STATUS_NULL; + sc_ext.sc_res = SC_EXT_RES_NULL; + + num_res = sizeof (sc_ext_mode) / sizeof (sc_ext_mode[0]); + + /* reset mode list of a external monitor */ + for (i = 0; i < num_res; i++) + { + sc_ext_mode[i].refresh = 0.0; + sc_ext_mode[i].mode_info = NULL; + } + return 1; +} + +void +e_mod_scrnconf_container_bg_canvas_visible_set(Eina_Bool visible) +{ + E_Manager *man = NULL; + E_Container *con = NULL; + Eina_List *m, *c; + + EINA_LIST_FOREACH(e_manager_list(), m, man) + { + EINA_LIST_FOREACH(man->containers, c, con) + { + if (visible) + ecore_evas_show(con->bg_ecore_evas); + else + ecore_evas_hide(con->bg_ecore_evas); + } + } +} diff --git a/src/e_mod_scrnconf.h b/src/e_mod_scrnconf.h new file mode 100755 index 0000000..bb5334a --- /dev/null +++ b/src/e_mod_scrnconf.h @@ -0,0 +1,36 @@ + +#ifndef E_MOD_SCRNCONF_H +#define E_MOD_SCRNCONF_H + +#define LOG_TAG "DEVICEMGR" +#include "dlog.h" + +void e_mod_scrnconf_external_init (); +void e_mod_scrnconf_external_deinit (); + +void e_mod_scrnconf_external_dialog_new (int sc_output); +void e_mod_scrnconf_external_dialog_free (void); + +int e_mod_scrnconf_external_get_output_from_xid (Ecore_X_Randr_Output output_xid); +int e_mod_scrnconf_external_get_default_res (int sc_output, int preferred_w, int preferred_h); + +int e_mod_scrnconf_external_get_output (void); +int e_mod_scrnconf_external_set_output (int sc_output); + +int e_mod_scrnconf_external_get_res (void); +int e_mod_scrnconf_external_set_res (int sc_res); + +int e_mod_scrnconf_external_get_status (void); +int e_mod_scrnconf_external_set_status (int sc_stat); + +int e_mod_scrnconf_external_set_dispmode (int sc_output, int sc_dispmode, int sc_res); +int e_mod_scrnconf_external_get_dispmode (void); + +int e_mod_scrnconf_external_send_current_status (void); + +int e_mod_scrnconf_external_reset (int sc_output); + +void e_mod_scrnconf_container_bg_canvas_visible_set(Eina_Bool visible); + +#endif // E_MOD_SCRNCONF_H + diff --git a/src/hib_devicemgr.c b/src/hib_devicemgr.c new file mode 100755 index 0000000..04319c2 --- /dev/null +++ b/src/hib_devicemgr.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include "hib_set.h" + +#define HIB_CHK(cond) {if (!(cond)) { SLOG(LOG_DEBUG, "DEVICEMGR", "[%s] : '%s' failed.\n", __func__, #cond); return; }} + +void +hibernation_set (Display *dpy) +{ + HIB_CHK (dpy); + + Window win = DefaultRootWindow(dpy); + XEvent xev; + Atom hib_atom = None; + + hib_atom = XInternAtom (dpy, STR_ATOM_HIB_SET, False); + + xev.xclient.window = win; + xev.xclient.type = ClientMessage; + xev.xclient.message_type = hib_atom; + xev.xclient.format = 32; + xev.xclient.data.s[0] = HIB_CMD_SET; + xev.xclient.data.s[1] = 0; + xev.xclient.data.s[2] = 0; + xev.xclient.data.s[3] = 0; + xev.xclient.data.s[4] = 0; + + XSendEvent(dpy, win, False, StructureNotifyMask, &xev); + XSync(dpy, False); +} + +void +hibernation_unset (Display *dpy) +{ + HIB_CHK (dpy); + + Window win = DefaultRootWindow(dpy); + XEvent xev; + Atom hib_atom = None; + + hib_atom = XInternAtom (dpy, STR_ATOM_HIB_SET, False); + + xev.xclient.window = win; + xev.xclient.type = ClientMessage; + xev.xclient.message_type = hib_atom; + xev.xclient.format = 32; + xev.xclient.data.s[0] = HIB_CMD_UNSET; + xev.xclient.data.s[1] = 0; + xev.xclient.data.s[2] = 0; + xev.xclient.data.s[3] = 0; + xev.xclient.data.s[4] = 0; + + XSendEvent(dpy, win, False, StructureNotifyMask, &xev); + XSync(dpy, False); +} + diff --git a/src/hib_devicemgr.h b/src/hib_devicemgr.h new file mode 100644 index 0000000..04536c2 --- /dev/null +++ b/src/hib_devicemgr.h @@ -0,0 +1,16 @@ +#ifndef HIB_DEVICEMGR_H +#define HIB_DEVICEMGR_H + +/* atom string */ +#define STR_ATOM_HIB_REQUEST "_HIB_REQUEST" + +/* hibernation command */ +typedef enum +{ + HIB_REQ_NULL, /* null */ + HIB_REQ_SET, /* set hibernation */ + HIB_REQ_UNSET, /* unset hibernation */ +} HIB_REQ; + +#endif // HIB_DEVICEMGR_H + diff --git a/src/rotation_devicemgr.c b/src/rotation_devicemgr.c new file mode 100755 index 0000000..f8d7e8a --- /dev/null +++ b/src/rotation_devicemgr.c @@ -0,0 +1,406 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * This file is a modified version of BSD licensed file and + * licensed under the Flora License, Version 1.1 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://floralicense.org/license/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Please, see the COPYING file for the original copyright owner and + * license. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "e_devicemgr_privates.h" +#include "rotation_devicemgr.h" + +#include "dlog.h" +#undef LOG_TAG +#define LOG_TAG "E17_EXTRA_MODULES" + +typedef struct _E_DM_Sensor_Rotation E_DM_Sensor_Rotation; + +struct _E_DM_Sensor_Rotation +{ + int handle; + Eina_Bool started; + enum auto_rotation_state state; + Ecore_Timer *retry_timer; + int retry_count; + Eina_Bool lock; + Eina_Bool connected; +}; + +/* static global variables */ +static E_DM_Sensor_Rotation rot; +static Ecore_X_Atom ATOM_DEVICE_ROTATION_ANGLE = 0; + +/* local subsystem functions */ +static Eina_Bool _sensor_connect(void); +static Eina_Bool _sensor_disconnect(void); +static Eina_Bool _sensor_connect_retry_timeout(void *data); +static void _sensor_rotation_changed_cb(unsigned int event_type, sensor_event_data_t *event, void *data); +static void _vconf_cb_lock_change(keynode_t *node, void *data); +static void _sensor_rotation_set(int ang); +static int _ang_get(enum auto_rotation_state state); + +/* externally accessible functions */ +Eina_Bool +e_mod_sf_rotation_init(void) +{ + int r = 0, lock = 0; + Eina_Bool res = EINA_FALSE; + + rot.connected = EINA_FALSE; + rot.retry_count = 0; + res = _sensor_connect(); + if (res) + { + r = vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &lock); + if (r) + { + ELBF(ELBT_ROT, 0, 0, + "ERR! AUTO_ROTATE_SCREEN_BOOL get failed. " + "r:%d lock:%d", r, lock); + } + else + { + rot.lock = !lock; + vconf_notify_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, + _vconf_cb_lock_change, + NULL); + ELBF(ELBT_ROT, 0, 0, + "AUTO_ROTATE_SCREEN_BOOL get succeeded. " + "lock:%d rot.locK%d", lock, rot.lock); + } + } + _sensor_rotation_set(0); + return EINA_TRUE; +} + +Eina_Bool +e_mod_sf_rotation_deinit(void) +{ + vconf_ignore_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, _vconf_cb_lock_change); + _sensor_disconnect(); + return EINA_TRUE; +} + +/* local subsystem functions */ +static Eina_Bool +_sensor_connect(void) +{ + int h, r, lock = 0; + if (rot.connected) return EINA_TRUE; + + if (rot.retry_timer) + { + ecore_timer_del(rot.retry_timer); + rot.retry_timer = NULL; + } + + rot.handle = -1; + rot.started = EINA_FALSE; + + h = sf_connect(AUTO_ROTATION_SENSOR); + if (h < 0) + { + ELB(ELBT_ROT, "ERR! sf_connect failed", h); + goto error; + } + + r = sf_register_event(h, AUTO_ROTATION_EVENT_CHANGE_STATE, + NULL, _sensor_rotation_changed_cb, NULL); + if (r < 0) + { + ELB(ELBT_ROT, "ERR! sf_register_event failed", r); + sf_disconnect(h); + goto error; + } + + r = sf_start(h, 0); + if (r < 0) + { + ELB(ELBT_ROT, "ERR! sf_start failed", r); + sf_unregister_event(h, AUTO_ROTATION_EVENT_CHANGE_STATE); + sf_disconnect(h); + goto error; + } + + rot.handle = h; + rot.started = EINA_TRUE; + rot.retry_count = 0; + rot.lock = EINA_FALSE; + rot.connected = EINA_TRUE; + + ELB(ELBT_ROT, "sf_connect succeeded", h); + return EINA_TRUE; + +error: + if (rot.retry_count <= 20) + { + rot.retry_timer = ecore_timer_add(10.0f, + _sensor_connect_retry_timeout, + NULL); + } + return EINA_FALSE; +} + +static Eina_Bool +_sensor_disconnect(void) +{ + int r; + if (!rot.connected) return EINA_TRUE; + + rot.lock = EINA_FALSE; + + if (rot.retry_timer) + { + ecore_timer_del(rot.retry_timer); + rot.retry_timer = NULL; + } + + rot.retry_count = 0; + + if (rot.handle < 0) + { + ELB(ELBT_ROT, "ERR! invalid handle", rot.handle); + goto error; + } + + if (rot.started) + { + r = sf_unregister_event(rot.handle, + AUTO_ROTATION_EVENT_CHANGE_STATE); + if (r < 0) + { + ELB(ELBT_ROT, "ERR! sf_unregister_event failed", r); + goto error; + } + r = sf_stop(rot.handle); + if (r < 0) + { + ELB(ELBT_ROT, "ERR! sf_stop failed", r); + goto error; + } + rot.started = EINA_TRUE; + } + + r = sf_disconnect(rot.handle); + if (r < 0) + { + ELB(ELBT_ROT, "ERR! sf_disconnect failed", r); + goto error; + } + + rot.handle = -1; + rot.connected = EINA_FALSE; + ELB(ELBT_ROT, "sf_disconnect succeeded", NULL); + return EINA_TRUE; +error: + return EINA_FALSE; +} + +static Eina_Bool +_sensor_connect_retry_timeout(void *data) +{ + int r = 0, lock = 0; + Eina_Bool res = EINA_FALSE; + + if (rot.retry_timer) + { + ecore_timer_del(rot.retry_timer); + rot.retry_timer = NULL; + } + rot.retry_count++; + ELB(ELBT_ROT, "retrying to connect sensor", rot.retry_count); + res = _sensor_connect(); + if (res) + { + r = vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &lock); + if (r) + { + ELBF(ELBT_ROT, 0, 0, + "ERR! AUTO_ROTATE_SCREEN_BOOL get failed. " + "r:%d lock:%d", r, lock); + } + else + { + rot.lock = !lock; + vconf_notify_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, + _vconf_cb_lock_change, + NULL); + ELBF(ELBT_ROT, 0, 0, + "AUTO_ROTATE_SCREEN_BOOL get succeeded. " + "lock:%d rot.locK%d", lock, rot.lock); + } + } + + return ECORE_CALLBACK_CANCEL; +} + +static int +_ang_get(enum auto_rotation_state state) +{ + E_Devicemgr_Config_Rotation *cr = NULL; + Eina_List *l = NULL; + int ang = -1, res = -1; + + /* change CW (SensorFW) to CCW(EFL) */ + switch (state) + { + case AUTO_ROTATION_DEGREE_0: ang = 0; break; + case AUTO_ROTATION_DEGREE_90: ang = 270; break; + case AUTO_ROTATION_DEGREE_180: ang = 180; break; + case AUTO_ROTATION_DEGREE_270: ang = 90; break; + default: + ELB(ELBT_ROT, "Unknown state", state); + break; + } + + EINA_LIST_FOREACH(_e_devicemgr_cfg->rotation, l, cr) + { + if (!cr) continue; + if (cr->angle == ang) + { + if (cr->enable) + res = ang; + break; + } + } + + return res; +} + +enum auto_rotation_state +_state_get(int ang) +{ + switch (ang) + { + case 0: + return AUTO_ROTATION_DEGREE_0; + case 270: + return AUTO_ROTATION_DEGREE_90; + case 180: + return AUTO_ROTATION_DEGREE_180; + case 90: + return AUTO_ROTATION_DEGREE_270; + default: + return AUTO_ROTATION_DEGREE_UNKNOWN; + } +} + +static void +_sensor_rotation_changed_cb(unsigned int event_type, + sensor_event_data_t *event, + void *data) +{ + enum auto_rotation_state state; + E_Manager *m = e_manager_current_get(); + E_Zone *zone = e_util_zone_current_get(m); + int ang = 0; + + if (rot.lock) return; + if (!zone) return; + if (event_type != AUTO_ROTATION_EVENT_CHANGE_STATE) return; + if (!event) return; + + state = *((enum auto_rotation_state*)(event->event_data)); + + ang = _ang_get(state); + + SECURE_SLOGD("[ROTATION] SENSOR ROT_CHANGE, state:%d angle:%d", state, ang); + ELBF(ELBT_ROT, 0, 0, "ROT_EV state:%d angle:%d", state, ang); + + e_zone_rotation_set(zone, ang); + + rot.state = state; + _sensor_rotation_set(ang); +} + +static void +_vconf_cb_lock_change(keynode_t *node, + void *data) +{ + E_Manager *m = NULL; + E_Zone *zone = NULL; + int lock = 0, z_ang = -1, ang = -1; + Eina_Bool res = EINA_FALSE; + if (!node) + { + ELB(ELBT_ROT, "ERR! node is NULL", 0); + return; + } + + m = e_manager_current_get(); + if (m) zone = e_util_zone_current_get(m); + + lock = !vconf_keynode_get_bool(node); + ELBF(ELBT_ROT, 0, 0, "ROT LOCK: %d->%d", rot.lock, lock); + + if (lock) + { + // disconnect sensor for reducing the current sinking. + _sensor_disconnect(); + if (zone) e_zone_rotation_set(zone, 0); + rot.state = AUTO_ROTATION_DEGREE_0; + } + else + { + // connect sensor for auto rotation. + res = _sensor_connect(); + ELB(ELBT_ROT, "_sensor_connect() res", res); + if (res) + { + sensor_data_t data; + if (sf_get_data(rot.handle, AUTO_ROTATION_BASE_DATA_SET, &data) < 0) + { + ELB(ELBT_ROT, "ERR! getting rotation failed", NULL); + } + else + { + ang = _ang_get(data.values[0]); + if (zone) z_ang = e_zone_rotation_get(zone); + if ((ang != -1) && (ang != z_ang)) + { + if (zone) e_zone_rotation_set(zone, ang); + rot.state = _state_get(ang); + _sensor_rotation_set(ang); + } + } + } + } + + rot.lock = lock; +} + +static void +_sensor_rotation_set(int ang) +{ + Ecore_X_Window root = ecore_x_window_root_first_get(); + unsigned int val = (unsigned int)ang; + + if (!ATOM_DEVICE_ROTATION_ANGLE) + ATOM_DEVICE_ROTATION_ANGLE = ecore_x_atom_get("_E_DEVICE_ROTATION_ANGLE"); + + ecore_x_window_prop_card32_set(root, + ATOM_DEVICE_ROTATION_ANGLE, + &val, 1); +} diff --git a/src/rotation_devicemgr.h b/src/rotation_devicemgr.h new file mode 100755 index 0000000..fa37946 --- /dev/null +++ b/src/rotation_devicemgr.h @@ -0,0 +1,7 @@ +#ifndef ROTATION_DEVICEMGR_H +#define ROTATION_DEVICEMGR_H + +/*TODO*/ + +#endif // ROTATION_DEVICEMGR_H + diff --git a/src/scrnconf_devicemgr.c b/src/scrnconf_devicemgr.c new file mode 100644 index 0000000..c5201af --- /dev/null +++ b/src/scrnconf_devicemgr.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include +#include "scrnconf_devicemgr.h" + +#define SCRNCONF_CHK(cond, val) {if (!(cond)) { fprintf (stderr, "[%s] : '%s' failed.\n", __func__, #cond); return val; }} + +int +scrnconf_ext_send_status (Display *dpy, Utilx_Scrnconf_Status sc_stat, Utilx_Scrnconf_Dispmode sc_dispmode) +{ + SCRNCONF_CHK (dpy, 0); + + Window win = DefaultRootWindow(dpy); + XEvent xev; + Atom scrnconf_atom = None; + + scrnconf_atom = XInternAtom (dpy, STR_ATOM_SCRNCONF_STATUS, False); + + xev.xclient.window = win; + xev.xclient.type = ClientMessage; + xev.xclient.message_type = scrnconf_atom; + xev.xclient.format = 32; + xev.xclient.data.s[0] = sc_stat; + xev.xclient.data.s[1] = sc_dispmode; + + XSendEvent(dpy, win, False, StructureNotifyMask, &xev); + XSync(dpy, False); + + return 1; +} + +int +scrnconf_ext_update_get_perperty (Display *dpy, char *str_output, char *str_stat, char *str_res, char *str_dispmode) +{ + SCRNCONF_CHK (dpy, 0); + + Window win = DefaultRootWindow(dpy); + XTextProperty xtp; + Atom scrnconf_atom = None; + char * str = NULL; + int size = 0; + + scrnconf_atom = XInternAtom (dpy, STR_ATOM_SCRNCONF_INFO, False); + + size = strlen(str_output) + strlen(str_stat) + strlen(str_res) + strlen(str_dispmode) + 4; + + str = calloc (size, sizeof(char)); + if (str) + { + snprintf (str, size, "%s,%s,%s,%s", str_output, str_stat, str_res, str_dispmode); + xtp.value = (unsigned char *)str; + xtp.format = 8; + xtp.encoding = XA_STRING; + xtp.nitems = size; + XSetTextProperty (dpy, win, &xtp, scrnconf_atom); + free(str); + } + + return 1; +} diff --git a/src/scrnconf_devicemgr.h b/src/scrnconf_devicemgr.h new file mode 100755 index 0000000..f625a90 --- /dev/null +++ b/src/scrnconf_devicemgr.h @@ -0,0 +1,36 @@ +#ifndef SCRNCONF_DEVICEMGR_H +#define SCRNCONF_DEVICEMGR_H + +#include +#include +#include + +#define STR_ATOM_SCRNCONF_DISPMODE_SET "_SCRNCONF_DISPMODE_SET" +#define STR_ATOM_SCRNCONF_INFO "_SCRNCONF_INFO" + +/* scrn conf output */ +typedef enum +{ + SC_EXT_OUTPUT_NULL, /* null */ + SC_EXT_OUTPUT_HDMI, /* hdmi output */ + SC_EXT_OUTPUT_VIRTUAL, /* virtual output */ +} SC_EXT_OUTPUT; + +/* scrn conf resolution */ +typedef enum +{ + SC_EXT_RES_NULL, /* null */ + SC_EXT_RES_1920X1080, /* 1920 x 1080 */ + SC_EXT_RES_1280X720, /* 1280 x 720 */ + SC_EXT_RES_720X480, /* 720 x 480 */ + SC_EXT_RES_720X576, /* 720 x 576 */ +} SC_EXT_RES; + +/* send status */ +int scrnconf_ext_send_status (Display *dpy, Utilx_Scrnconf_Status sc_stat, Utilx_Scrnconf_Dispmode sc_dispmode); + +/* update screen configuration of a external monitor */ +int scrnconf_ext_update_get_perperty (Display *dpy, char *str_output, char *str_stat, char *str_res, char *str_dispmode); + +#endif // SCRNCONF_DEVICEMGR_H + diff --git a/src/virt_monitor_devicemgr.c b/src/virt_monitor_devicemgr.c new file mode 100755 index 0000000..0af5a5b --- /dev/null +++ b/src/virt_monitor_devicemgr.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include "virt_mon_set.h" + +#define VIRT_MON_CHK(cond) {if (!(cond)) { SLOG(LOG_DEBUG, "DEVICEMGR", "[%s] : '%s' failed.\n", __func__, #cond); return; }} + +/* set the virtual monitor to connect */ +void +virtual_monitor_set_connect (Display *dpy) +{ + VIRT_MON_CHK (dpy); + + Window win = DefaultRootWindow(dpy); + XEvent xev; + Atom virt_mon_atom = None; + + virt_mon_atom = XInternAtom (dpy, STR_ATOM_VIRT_MON_SET, False); + + xev.xclient.window = win; + xev.xclient.type = ClientMessage; + xev.xclient.message_type = virt_mon_atom; + xev.xclient.format = 32; + xev.xclient.data.s[0] = VM_CMD_SET; + xev.xclient.data.s[1] = 0; + xev.xclient.data.s[2] = 0; + xev.xclient.data.s[3] = 0; + xev.xclient.data.s[4] = 0; + + XSendEvent(dpy, win, False, StructureNotifyMask, &xev); + XSync(dpy, False); +} + +/* set the virtual monitor to disconnect */ +void +virtual_monitor_set_disconnect (Display *dpy) +{ + VIRT_MON_CHK (dpy); + + Window win = DefaultRootWindow(dpy); + XEvent xev; + Atom virt_mon_atom = None; + + virt_mon_atom = XInternAtom (dpy, STR_ATOM_VIRT_MON_SET, False); + + xev.xclient.window = win; + xev.xclient.type = ClientMessage; + xev.xclient.message_type = virt_mon_atom; + xev.xclient.format = 32; + xev.xclient.data.s[0] = VM_CMD_UNSET; + xev.xclient.data.s[1] = 0; + xev.xclient.data.s[2] = 0; + xev.xclient.data.s[3] = 0; + xev.xclient.data.s[4] = 0; + + XSendEvent(dpy, win, False, StructureNotifyMask, &xev); + XSync(dpy, False); +} + + diff --git a/src/virt_monitor_devicemgr.h b/src/virt_monitor_devicemgr.h new file mode 100644 index 0000000..f6c608b --- /dev/null +++ b/src/virt_monitor_devicemgr.h @@ -0,0 +1,16 @@ +#ifndef VIRT_MONITOR_DEVICEMGR_H +#define VIRT_MONITOR_DEVICEMGR_H + +/* atom string */ +#define STR_ATOM_VIRT_MONITOR_REQUEST "_VIRT_MONITOR_REQUEST" + +/* virtual monitor command */ +typedef enum +{ + VM_REQ_NULL, /* null */ + VM_REQ_PLUG, /* virtual monitor plugged */ + VM_REQ_UNPLUG, /* virtual monitor unplugged */ +} VM_REQ; + +#endif // VIRT_MONITOR_DEVICEMGR_H + -- 2.7.4