From b35b933f17e9dc79300b15e12a57250300a8d54c Mon Sep 17 00:00:00 2001 From: Jinkun Jang Date: Wed, 13 Mar 2013 01:54:34 +0900 Subject: [PATCH] Tizen 2.1 base --- AUTHORS | 3 + CMakeLists.txt | 48 + LICENSE.APLv2 | 206 ++++ NOTICE | 3 + TC/_export_env.sh | 8 + TC/_export_target_env.sh | 7 + TC/build.sh | 16 + TC/clean.sh | 11 + TC/config | 2 + TC/execute.sh | 15 + TC/testcase/Makefile | 26 + TC/testcase/tslist | 1 + TC/testcase/utc_utilx_test.c | 79 ++ TC/tet_scen | 7 + TC/tetbuild.cfg | 5 + TC/tetclean.cfg | 5 + TC/tetexec.cfg | 5 + packaging/libslp-utilx.spec | 71 ++ utilX.h | 1683 +++++++++++++++++++++++++++++++++ utilX.pc | 12 + utilX.pc.in | 12 + util_x11.h | 27 + x11.c | 2144 ++++++++++++++++++++++++++++++++++++++++++ 23 files changed, 4396 insertions(+) create mode 100644 AUTHORS create mode 100644 CMakeLists.txt create mode 100644 LICENSE.APLv2 create mode 100644 NOTICE create mode 100755 TC/_export_env.sh create mode 100755 TC/_export_target_env.sh create mode 100755 TC/build.sh create mode 100755 TC/clean.sh create mode 100755 TC/config create mode 100755 TC/execute.sh create mode 100755 TC/testcase/Makefile create mode 100755 TC/testcase/tslist create mode 100644 TC/testcase/utc_utilx_test.c create mode 100755 TC/tet_scen create mode 100755 TC/tetbuild.cfg create mode 100755 TC/tetclean.cfg create mode 100755 TC/tetexec.cfg create mode 100644 packaging/libslp-utilx.spec create mode 100644 utilX.h create mode 100644 utilX.pc create mode 100644 utilX.pc.in create mode 100644 util_x11.h create mode 100644 x11.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..5a3e1bb --- /dev/null +++ b/AUTHORS @@ -0,0 +1,3 @@ +Doyoun Kang +Sung-Jin Park +Gwangyeong Mun diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..df9fa0d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,48 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(utilX C) + +SET(SRCS x11.c) +SET(HEADERS utilX.h) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "\${prefix}") +SET(LIBDIR "\${prefix}/lib") +SET(INCLUDEDIR "\${prefix}/include") +SET(VERSION_MAJOR 1) +SET(VERSION "${VERSION_MAJOR}.1.0") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkgs REQUIRED x11 xext xv xdamage libdrm libdrm_slp libdri2 xrandr) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g") +#SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -finstrument-functions") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"") +ADD_DEFINITIONS("-DFACTORYFS=\"${PREFIX}\"") +#ADD_DEFINITIONS("-DDEBUG") + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION}) + +CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY) + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib COMPONENT RuntimeLibraries) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION lib/pkgconfig) + +FOREACH(hfile ${HEADERS}) + INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${hfile} DESTINATION include) +ENDFOREACH(hfile) + +#ADD_SUBDIRECTORY(test) + diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100644 index 0000000..dc0cc6d --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,206 @@ +Copyright (c) 2012 Samsung Electronics Co., Ltd. All Rights Reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + 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. + + 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, + 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 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 in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) 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 + + (d) 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. + + 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 Apache License to your work. + + To apply the Apache 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 Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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/NOTICE b/NOTICE new file mode 100644 index 0000000..b0bbc38 --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +Copyright (c) 2012 Samsung Electronics Co., Ltd. All Rights Reserved. +Except as noted, this software is licensed under the Apache License, Version 2.0. +Please, see the LICENSE.APLv2 file for Apache License, Version 2 terms and conditions. diff --git a/TC/_export_env.sh b/TC/_export_env.sh new file mode 100755 index 0000000..72a11ec --- /dev/null +++ b/TC/_export_env.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +. ./config +export TET_INSTALL_PATH=$TET_INSTALL_HOST_PATH # tetware root path +export TET_TARGET_PATH=$TET_INSTALL_PATH/tetware-target # tetware target path +export PATH=$TET_TARGET_PATH/bin:$PATH +export LD_LIBRARY_PATH=$TET_TARGET_PATH/lib/tet3:$LD_LIBRARY_PATH +export TET_ROOT=$TET_TARGET_PATH diff --git a/TC/_export_target_env.sh b/TC/_export_target_env.sh new file mode 100755 index 0000000..5ddaa53 --- /dev/null +++ b/TC/_export_target_env.sh @@ -0,0 +1,7 @@ +#!/bin/sh +. ./config +export TET_INSTALL_PATH=$TET_INSTALL_TARGET_PATH # path to path +export TET_TARGET_PATH=$TET_INSTALL_PATH/tetware-target +export PATH=$TET_TARGET_PATH/bin:$PATH +export LD_LIBRARY_PATH=$TET_TARGET_PATH/lib/tet3:$LD_LIBRARY_PATH +export TET_ROOT=$TET_TARGET_PATH diff --git a/TC/build.sh b/TC/build.sh new file mode 100755 index 0000000..72aad6c --- /dev/null +++ b/TC/build.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +. ./_export_env.sh # setting environment variables + +export TET_SUITE_ROOT=`pwd` +FILE_NAME_EXTENSION=`date +%s` + +RESULT_DIR=results +HTML_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.html +JOURNAL_RESULT=$RESULT_DIR/build-tar-result-$FILE_NAME_EXTENSION.journal + +mkdir -p $RESULT_DIR + +tcc -c -p ./ +tcc -b -j $JOURNAL_RESULT -p ./ +grw -c 7 -f chtml -o $HTML_RESULT $JOURNAL_RESULT diff --git a/TC/clean.sh b/TC/clean.sh new file mode 100755 index 0000000..29743e0 --- /dev/null +++ b/TC/clean.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +. ./_export_env.sh # setting environment variables + +export TET_SUITE_ROOT=`pwd` +RESULT_DIR=results + +tcc -c -p ./ # executing tcc, with clean option (-c) +rm -r $RESULT_DIR +rm -r tet_tmp_dir +rm testcase/tet_captured diff --git a/TC/config b/TC/config new file mode 100755 index 0000000..c7eae66 --- /dev/null +++ b/TC/config @@ -0,0 +1,2 @@ +TET_INSTALL_HOST_PATH=/home/nfs_mount/TETware +TET_INSTALL_TARGET_PATH=/mnt/nfs/TETware diff --git a/TC/execute.sh b/TC/execute.sh new file mode 100755 index 0000000..a4f6095 --- /dev/null +++ b/TC/execute.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. ./_export_target_env.sh # setting environment variables + +export TET_SUITE_ROOT=`pwd` +FILE_NAME_EXTENSION=`date +%s` + +RESULT_DIR=results +HTML_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.html +JOURNAL_RESULT=$RESULT_DIR/exec-tar-result-$FILE_NAME_EXTENSION.journal + +mkdir -p $RESULT_DIR + +tcc -e -j $JOURNAL_RESULT -p ./ +grw -c 3 -f chtml -o $HTML_RESULT $JOURNAL_RESULT diff --git a/TC/testcase/Makefile b/TC/testcase/Makefile new file mode 100755 index 0000000..dbbc399 --- /dev/null +++ b/TC/testcase/Makefile @@ -0,0 +1,26 @@ +CC = gcc + +C_FILES = $(shell ls *.c) + +PKGS = elementary ecore-x ecore evas x11 dlog glib-2.0 utilX + +LDFLAGS += $(TET_ROOT)/lib/tet3/tcm_s.o +LDFLAGS += -L$(TET_ROOT)/lib/tet3 -ltcm_s +LDFLAGS += -L$(TET_ROOT)/lib/tet3 -lapi_s +LDFLAGS += `pkg-config --libs $(PKGS)` + +CFLAGS += `pkg-config --cflags $(PKGS)` +CFLAGS += -I. +CFLAGS += -I$(TET_ROOT)/inc/tet3 +CFLAGS += -Wall + +#TARGETS = $(C_FILES:%.c=tc-%) +TCS := $(shell ls -1 *.c | cut -d. -f1) + +all: $(TCS) + +%: %.c + $(CC) -o $@ $< $(CFLAGS) $(LDFLAGS) + +clean: + rm -f $(TCS) diff --git a/TC/testcase/tslist b/TC/testcase/tslist new file mode 100755 index 0000000..81af698 --- /dev/null +++ b/TC/testcase/tslist @@ -0,0 +1 @@ +/testcase/utc_utilx_test diff --git a/TC/testcase/utc_utilx_test.c b/TC/testcase/utc_utilx_test.c new file mode 100644 index 0000000..7934c62 --- /dev/null +++ b/TC/testcase/utc_utilx_test.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#include +#include +#include +#include + + +static void startup(void); +static void cleanup(void); + +void (*tet_startup)(void) = startup; +void (*tet_cleanup)(void) = cleanup; + +static void utc_utilx_enable_indicator(void); + + +struct tet_testlist tet_testlist[] = { + { utc_utilx_enable_indicator, 1 }, + // Do not remove below line + { NULL, 0 }, +}; + +static void startup(void) +{ + /* start of TC */ +} + +static void cleanup(void) +{ + /* end of TC */ +} + + +/** + * @brief test case of utilx_enable_indicator() + */ +static void utc_utilx_enable_indicator(void) +{ + Display* dpy; + Window root, win; + int ret; + + dpy = XOpenDisplay(NULL); + root = XDefaultRootWindow(dpy); + + win = XCreateSimpleWindow(dpy, root, 0, 0, 480, 800, 2, BlackPixel(dpy,0), WhitePixel(dpy,0)); + XMapWindow(dpy, win); + + // If the win want to show indicator, enables indicator. + utilx_enable_indicator(dpy, win, 1); + XFlush(dpy); + + ret = 1; + + if(ret) + { + dts_pass("utc_efl_util_set_notification_window_level_positive", "passed"); + } + else + { + dts_fail("utc_efl_util_set_notification_window_level_positive", "failed"); + } +} + diff --git a/TC/tet_scen b/TC/tet_scen new file mode 100755 index 0000000..03f029a --- /dev/null +++ b/TC/tet_scen @@ -0,0 +1,7 @@ +all + ^TEST +##### Scenarios for TEST ##### + +# Test scenario +TEST + :include:/testcase/tslist diff --git a/TC/tetbuild.cfg b/TC/tetbuild.cfg new file mode 100755 index 0000000..f7eda55 --- /dev/null +++ b/TC/tetbuild.cfg @@ -0,0 +1,5 @@ +TET_OUTPUT_CAPTURE=True # capture option for build operation checking +TET_BUILD_TOOL=make # build with using make command +TET_BUILD_FILE=-f Makefile # execution file (Makefile) for build +TET_API_COMPLIANT=True # use TET API in Test Case ? +TET_PASS_TC_NAME=True # report passed TC name in Journal file? diff --git a/TC/tetclean.cfg b/TC/tetclean.cfg new file mode 100755 index 0000000..02d7030 --- /dev/null +++ b/TC/tetclean.cfg @@ -0,0 +1,5 @@ +TET_OUTPUT_CAPTURE=True # capture option +TET_CLEAN_TOOL= make clean # clean tool +TET_CLEAN_FILE= Makefile # file for clean +TET_API_COMPLIANT=True # TET API useage +TET_PASS_TC_NAME=True # showing name , passed TC diff --git a/TC/tetexec.cfg b/TC/tetexec.cfg new file mode 100755 index 0000000..ef3e452 --- /dev/null +++ b/TC/tetexec.cfg @@ -0,0 +1,5 @@ +TET_OUTPUT_CAPTURE=True # capturing execution or not +TET_EXEC_TOOL= # ex) exec : execution tool set up/ Optional +TET_EXEC_FILE= # ex) exectool : execution file/ Optional +TET_API_COMPLIANT=True # Test case or Tool usesTET API? +TET_PASS_TC_NAME=True # showing Passed TC name ? diff --git a/packaging/libslp-utilx.spec b/packaging/libslp-utilx.spec new file mode 100644 index 0000000..81988e8 --- /dev/null +++ b/packaging/libslp-utilx.spec @@ -0,0 +1,71 @@ +#sbs-git:slp/pkgs/l/libslp-utilx libslp-utilx 0.1.7 5957503c84e65113399e346c7d5618e73957d6ff +Name: libslp-utilx +Summary: utilX +Version: 0.1.16 +Release: 1.1 +Group: System/Libraries +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +BuildRequires: cmake +BuildRequires: pkgconfig(libdri2) +BuildRequires: pkgconfig(dri2proto) +BuildRequires: pkgconfig(x11) +BuildRequires: pkgconfig(xext) +BuildRequires: pkgconfig(xv) +BuildRequires: pkgconfig(xdamage) +BuildRequires: pkgconfig(xrandr) +BuildRequires: pkgconfig(libdrm) +BuildRequires: pkgconfig(libdrm_slp) + +%description +Utility functions for the XWindow + + +%package devel +Summary: utilX +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +Utility functions for the XWindow (developement files) + +%prep +%setup -q + + +%build +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} + + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + +# for license notification +mkdir -p %{buildroot}/usr/share/license +cp %{_builddir}/%{buildsubdir}/LICENSE.APLv2 %{buildroot}/usr/share/license/%{name} + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + + +%files +%defattr(-,root,root,-) +/usr/lib/libutilX.so.* +/usr/share/license/%{name} + +%files devel +%defattr(-,root,root,-) +/usr/include/utilX.h +/usr/lib/libutilX.so +/usr/lib/pkgconfig/utilX.pc + + + + diff --git a/utilX.h b/utilX.h new file mode 100644 index 0000000..45bd0e2 --- /dev/null +++ b/utilX.h @@ -0,0 +1,1683 @@ +/* + * libslp-utilx + * + Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + * + */ + +#ifndef __SAMSUNG_LINUX_UTIL_X11_H__ +#define __SAMSUNG_LINUX_UTIL_X11_H__ + +#ifdef __GNUC__ +#define DEPRECATED __attribute__((deprecated)) +#else +#define DEPRECATED +#endif + +/** + * @defgroup utilX X11 utilities + * @ingroup lib + * @brief Samsung Linux platform X11 utilties + * + * Common X11 utilities + * You can use this API with #include + */ + +/** + * @addtogroup utilX + * @{ + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define KEY_VOLUMEUP "XF86AudioRaiseVolume" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Volume Up' key */ +#define KEY_VOLUMEDOWN "XF86AudioLowerVolume" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Volume Down' key */ + +#define KEY_CAMERA "XF86WebCam" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Half-Press of Camera' key */ +#define KEY_CONFIG "XF86Pictures" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Full-Press of Camera' key */ + +#define KEY_POWER "XF86PowerOff" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Power' key */ +#define KEY_PAUSE "XF86Standby" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Pause' key */ +#define KEY_CANCEL "Cancel" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Cancel' key */ + +// Earjack/BT Headset/Multimedia keys +#define KEY_PLAYCD "XF86AudioPlay" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Play Audio' key */ +#define KEY_STOPCD "XF86AudioStop" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Stop Audio' key */ +#define KEY_PAUSECD "XF86AudioPause" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Pause Audio' key */ +#define KEY_NEXTSONG "XF86AudioNext" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Next Song' key */ +#define KEY_PREVIOUSSONG "XF86AudioPrev" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Previous Song' key */ +#define KEY_REWIND "XF86AudioRewind" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Rewind Song' key */ +#define KEY_FASTFORWARD "XF86AudioForward" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Forward Song' key */ +#define KEY_MEDIA "XF86AudioMedia" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Media' key */ +#define KEY_PLAYPAUSE "XF86AudioPlay" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'PlayPause' key */ +#define KEY_MUTE "XF86AudioMute" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Mute' key */ + +// 3-Touch key +#define KEY_SEND "XF86Send" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Send' key */ +#define KEY_SELECT "XF86Phone" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Home' key */ +#define KEY_END "XF86Stop" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'End' key */ + +// Renamed 3-Touch key +#define KEY_MENU "XF86Send" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Send' key */ +#define KEY_HOME "XF86Phone" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Home' key */ +#define KEY_BACK "XF86Stop" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'End' key */ + +//Other functions keys +#define KEY_HOMEPAGE "XF86HomePage" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'HomePage' key */ +#define KEY_WEBPAGE "XF86WWW" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'WWW' key */ +#define KEY_MAIL "XF86Mail" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Mail' key */ +#define KEY_SCREENSAVER "XF86ScreenSaver" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'ScreenSaver' key */ +#define KEY_BRIGHTNESSUP "XF86MonBrightnessUp" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'BrightnessUp' key */ +#define KEY_BRIGHTNESSDOWN "XF86MonBrightnessDown" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'BrightnessDown' key */ +#define KEY_SOFTKBD "XF86MenuKB" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Soft keyboard(toggle)' key */ +#define KEY_QUICKPANEL "XF86Tools" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Quick panel(toggle)' key */ +#define KEY_TASKSWITCH "XF86TaskPane" /**< this macro means the XKeySym (XServer Key Symbol) corresponds to 'Task switcher(toggle)' key */ + +#define LEN_KEY_VOLUMEUP 20 /**< this macro is the length of string corresponds to 'Volume Up' key */ +#define LEN_KEY_VOLUMEDOWN 20 /**< this macro is the length of string corresponds to 'Volume Down' key */ + +#define LEN_KEY_CAMERA 10 /**< this macro is the length of string corresponds to 'Half-Press of Camera' key */ +#define LEN_KEY_CONFIG 12 /**< this macro is the length of string corresponds to 'Full-Press of Camera' key */ + +#define LEN_KEY_POWER 12 /**< this macro is the length of string corresponds to 'Power' key */ +#define LEN_KEY_PAUSE 11 /**< this macro is the length of string corresponds to 'Pause' key */ + +// Earjack/BT Headset/Multimedia keys +#define LEN_KEY_PLAYCD 13/**< this macro is the length of string corresponds to 'Play Audio' key */ +#define LEN_KEY_STOPCD 13/**< this macro is the length of string corresponds to 'Stop Audio' key */ +#define LEN_KEY_PAUSECD 14/**< this macro is the length of string corresponds to 'Pause Audio' key */ +#define LEN_KEY_NEXTSONG 13/**< this macro is the length of string corresponds to 'Next Song' key */ +#define LEN_KEY_PREVIOUSSONG 13/**< this macro is the length of string corresponds to 'Previous Song' key */ +#define LEN_KEY_REWIND 15/**< this macro is the length of string corresponds to 'Rewind Song' key */ +#define LEN_KEY_FASTFORWARD 16/**< this macro is the length of string corresponds to 'Forwand Song' key */ +#define LEN_KEY_MEDIA 14/**< this macro is the length of string corresponds to 'Media' key */ +#define LEN_KEY_PLAYPAUSE 13 /**< this macro is the length of string corresponds to 'PlayPause' key */ +#define LEN_KEY_MUTE 13 /**< this macro is the length of string corresponds to 'Mute' key */ + +// 3-Touch key +#define LEN_KEY_SEND 8 /**< this macro is the length of string corresponds to 'Send' key */ +#define LEN_KEY_SELECT 9 /**< this macro is the length of string corresponds to 'Home' key */ +#define LEN_KEY_END 8 /**< this macro is the length of string corresponds to 'End' key */ + +// Renamed 3-Touch key +#define LEN_KEY_MENU 8 /**< this macro is the length of string corresponds to 'Send' key */ +#define LEN_KEY_HOME 9 /**< this macro is the length of string corresponds to 'Home' key */ +#define LEN_KEY_BACK 8 /**< this macro is the length of string corresponds to 'End' key */ + +//Other functions keys +#define LEN_KEY_HOMEPAGE 12 /**< this macro is the length of string corresponds to 'HomePage' key */ +#define LEN_KEY_WEBPAGE 7 /**< this macro is the length of string corresponds to 'WWW' key */ +#define LEN_KEY_MAIL 8 /**< this macro is the length of string corresponds to 'Mail' key */ +#define LEN_KEY_SCREENSAVER 15 /**< this macro is the length of string corresponds to 'ScreenSaver' key */ +#define LEN_KEY_BRIGHTNESSUP 19 /**< this macro is the length of string corresponds to 'BrightnessUp' key */ +#define LEN_KEY_BRIGHTNESSDOWN 21 /**< this macro is the length of string corresponds to 'BrightnessDown' key */ + +#define LEN_KEY_SOFTKBD 10 /**< this macro is the length of string corresponds to 'Soft keyboard(toggle)' key */ +#define LEN_KEY_QUICKPANEL 9 /**< this macro is the length of string corresponds to 'Quick panel(toggle)' key */ +#define LEN_KEY_TASKSWITCH 12 /**< this macro is the length of string corresponds to 'Task switcher(toggle)' key */ + +#define OR_EXCLUSIVE_GRAB 0xf00000 /**< this means that the client window will always get the grabbed-key exclusively regardless of the position on the window stack but the grab is overridable by the other client window */ +#define EXCLUSIVE_GRAB 0x0f0000 /**< this means that the client window will always get the grabbed-key exclusively regardless of the position on the window stack */ +#define TOP_POSITION_GRAB 0x00f000 /**< this means that the client window will get the grabbed-key only when on the top of the grabbing-window stack */ +#define SHARED_GRAB 0x000f00 /**< this means that the client window will get the grabbed-key together with the other client window(s) */ +#define GRAB_MODE_MASK 0xffff00 /**< this mask will be used for getting the key-grab mode of a client window */ + +#define EXCLUSIVE_GRABBED_ALREADY 1 /**< this means that the client window is grabbing the key already in EXCLUSIVE mode */ + +#define STR_ATOM_GRAB_KEY "_GRAB_KEY" /**< this is an XATOM for getting/setting the property for grabbing a key for a window */ +#define STR_ATOM_GRAB_EXCL_WIN "_GRAB_EXCL_WIN_KEYCODE" /**< this means that the key was grabbed by a client window in EXCLUSIVE mod */ +#define STR_ATOM_GRAB_OR_EXCL_WIN "_GRAB_OR_EXCL_WIN_KEYCODE" /**< this means that the key was grabbed by a client window in OR_EXCLUSIVE mod */ + +#define STR_ATOM_SCRNCONF_STATUS "_SCRNCONF_STATUS" /**< this is an XATOM for getting the status of the screen configuration through the client message */ + +/** + * @brief Enumeration of screen configuration status + */ +typedef enum _Utilx_Scrnconf_Status +{ + UTILX_SCRNCONF_STATUS_NULL, /**< screen configuration status is null */ + UTILX_SCRNCONF_STATUS_CONNECT, /**< screen configuration status is connect */ + UTILX_SCRNCONF_STATUS_ACTIVE /**< screen configuration status is active */ +} Utilx_Scrnconf_Status; + +/** + * @brief Enumeration of screen configuration display mode + */ +typedef enum _Utilx_Scrnconf_Dispmode +{ + UTILX_SCRNCONF_DISPMODE_NULL, /**< display mode of screen configuration is null */ + UTILX_SCRNCONF_DISPMODE_CLONE, /**< display mode of screen configuration is clone */ + UTILX_SCRNCONF_DISPMODE_EXTENDED /**< display mode of screen configuration is extended */ +} Utilx_Scrnconf_Dispmode; + + +/** + * @brief Enumeration of key status + */ +typedef enum _Utilx_Key_Status +{ + UTILX_KEY_STATUS_PRESSED, /**< key status is pressed */ + UTILX_KEY_STATUS_RELEASED, /**< key status is released */ + UTILX_KEY_STATUS_UNKNOWN /** < key status is unknown or error happened */ +} Utilx_Key_Status; + +/** + * @brief Enumeration of notification window's priority level + */ +typedef enum _Utilx_Notification_Level +{ + UTILX_NOTIFICATION_LEVEL_LOW, /**< low level notification */ + UTILX_NOTIFICATION_LEVEL_NORMAL, /**< normal level notification*/ + UTILX_NOTIFICATION_LEVEL_HIGH /**< high level notification */ +} Utilx_Notification_Level; + +/** + * @brief Enumeration of Compositing Window Manager's Effect Type + */ +typedef enum _Utilx_Effect_Type +{ + UTILX_EFFECT_TYPE_MAP, /**< Effect for Window's Map Notify Event */ + UTILX_EFFECT_TYPE_UNMAP, /**< Effect for Window's UnMap Notify Event */ + UTILX_EFFECT_TYPE_RAISEABOVE, /**< Effect for Window's Configure Notify ( RaiseAbove case ) Event */ + UTILX_EFFECT_TYPE_ROTATION, /**< Effect for Window's Rotation Property Change Notify Event ( X Property: ECORE_X_ATOM_E_ILLUME_ROTATE_WINDOW_ANGLE ) */ + UTILX_EFFECT_TYPE_FOCUSIN, /**< Effect for Window's FocusIn Event ( E17's Event: E_EVENT_BORDER_FOCUS_IN ) */ + UTILX_EFFECT_TYPE_FOCUSOUT /**< Effect for Window's FocusOut Event ( E17's Event : E_EVENT_BORDER_FOCUS_OUT ) */ +} Utilx_Effect_Type; + +/** + * @brief Enumeration of Compositing Window Manager's Effect Style + */ +typedef enum _Utilx_Effect_Style +{ + UTILX_EFFECT_STYLE_DEFAULT, /**< Default Effect Style for Effect Type */ + UTILX_EFFECT_STYLE_NONE, /**< None of Effect Style for Effect Type */ + UTILX_EFFECT_STYLE_CUSTOM0, /**< Custom0 Effect Style for Effect Type */ + UTILX_EFFECT_STYLE_CUSTOM1, /**< Custom1 Effect Style for Effect Type */ + UTILX_EFFECT_STYLE_CUSTOM2, /**< Custom2 Effect Style for Effect Type */ + UTILX_EFFECT_STYLE_CUSTOM3, /**< Custom3 Effect Style for Effect Type */ + UTILX_EFFECT_STYLE_CUSTOM4, /**< Custom4 Effect Style for Effect Type */ + UTILX_EFFECT_STYLE_CUSTOM5, /**< Custom5 Effect Style for Effect Type */ + UTILX_EFFECT_STYLE_CUSTOM6, /**< Custom6 Effect Style for Effect Type */ + UTILX_EFFECT_STYLE_CUSTOM7, /**< Custom7 Effect Style for Effect Type */ + UTILX_EFFECT_STYLE_CUSTOM8, /**< Custom8 Effect Style for Effect Type */ + UTILX_EFFECT_STYLE_CUSTOM9 /**< Custom9 Effect Style for Effect Type */ +} Utilx_Effect_Style; + +/** + * @brief Enumeration of opaque state + */ +typedef enum _Utilx_Opaque_State +{ + UTILX_OPAQUE_STATE_OFF = 0, /**< Transparent state */ + UTILX_OPAQUE_STATE_ON = 1, /**< Opaque state */ +} Utilx_Opaque_State; + +/** + * @brief Enumeration of Fb's type + */ +typedef enum _Utilx_Fb_Type +{ + UTILX_FB_TYPE_NONE = 0, /**< None type */ + UTILX_FB_TYPE_UI = 1, /**< Framebuffer type is 'UI' */ + UTILX_FB_TYPE_OVERLAY = 2, /**< Framebuffer type is 'Overlay' */ +} Utilx_Fb_Type; + +/** + * @brief Structure of screen configuration information + */ +typedef struct _UtilxScrnConf +{ + char *str_output; /**< string value for the connector type */ + Utilx_Scrnconf_Status status; /**< status of screen configurtaion */ + char *str_resolution; /**< string value for the resolution to be active status */ + Utilx_Scrnconf_Dispmode dispmode; /**< display mode of screen configuration to be active status */ +} UtilxScrnConf; + +/** + * @fn ScrnConf *utilx_scrnconf_allocate(void) + * @brief allocate the UtilxScrnConf structure + * + * This function allocate the UtilxScrnConf structure.\n + * + * @remark This is used only application which want to know the screen configuration info. + * @pre This api does not require any pre-condition. + * @post This api does not change any condition. + * @see utilx_scrnconf_allocate + * @par Example + @code + #include + ... + + UtilxScrnConf *scrnconf = NULL; + + // Allocate the UtilxScrnConf structure + scrnconf = utilx_scrnconf_allocate(); + ... + @endcode + */ +UtilxScrnConf *utilx_scrnconf_allocate (void); + +/** + * @fn void utilx_scrnconf_free (UtilxScrnConf *scrnconf) + * @brief free the UtilxScrnConf structure + * + * This function free the UtilxScrnConf structure.\n + * + * @param[in] scrnconf Specifies the UtilxScrnConf structure + * @return instance of the UtilxScrnConf structure + * @remark This is used only application which want to know the screen configuration info. + * @pre This api does not require any pre-condition. + * @post This api does not change any condition. + * @see utilx_scrnconf_free + * @par Example + @code + #include + ... + + UtilxScrnConf *scrnconf = NULL; + + // Allocate the UtilxScrnConf structure + scrnconf = utilx_scrnconf_allocate(); + ... + + // Free the UtilxScrnConf structure + utilx_scrnconf_free(scrnconf); + ... + @endcode + */ +void utilx_scrnconf_free (UtilxScrnConf *scrnconf); + +/** + * @fn void utilx_scrnconf_get_info (Display *dpy, UtilxScrnConf *scrnconf) + * @brief get the information of the screen configuration + * + * This function get the information of the screen configuration.\n + * + * This function is a asynchronous call. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] scrnconf Specifies the information structure of the screen configuration + * @remark This is used only application which want to know the screen configuration info. + * @pre This api does not require any pre-condition. + * @post This api does not change any condition. + * @see utilx_scrnconf_get_info + * @par Example + @code + #include + #include + ... + + Display* dpy; + UtilxScrnConf *scrnconf = NULL; + int ret = 0; + + dpy = XOpenDisplay (NULL); + + // Allocate the UtilxScrnConf structure + scrnconf = utilx_scrnconf_allocate(); + ... + + // Set the display mode for the screen configuration + ret = utilx_scrnconf_get_info (dpy, scrnconf); + ... + + // Free the UtilxScrnConf structure + utilx_scrnconf_free(scrnconf); + ... + + @endcode + */ +int utilx_scrnconf_get_info (Display *dpy, UtilxScrnConf *scrnconf); + + +/** + * @fn void utilx_scrnconf_set_dispmode (Display *dpy, Utilx_Scrnconf_Dispmode dispmode) + * @brief set the display mode for the screen configuration + * + * This function set the display mode for the screen configuration.\n + * + * This function is a asynchronous call. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] dipmode Specifies the display mode of the screen configuration + * @return 1 if setting the dispmode is succeeded, 0 if setting the dispmode is failed. + * @remark This is used only application which want to set the display mode of the screen configuration. + * @pre This api does not require any pre-condition. + * @post This api does not change any condition. + * @see utilx_scrnconf_set_dispmode + * @par Example + @code + #include + #include + ... + + Display* dpy; + + dpy = XOpenDisplay (NULL); + + // Set the display mode for the screen configuration + utilx_scrnconf_set_dispmode (dpy, UTILX_SCRNCONF_DISPMODE_CLONE); + ... + @endcode + */ +int utilx_scrnconf_set_dispmode (Display *dpy, Utilx_Scrnconf_Dispmode dispmode); + + +/** + * @fn void utilx_set_system_notification_level (Display* dpy, Window win, Utilx_Notification_Level level) + * @brief Sets the priority level for the specified notification window + * + * This function sets the priority level of the notification windows.\n + * Every notification window has a base priority level by the notification window's priority value. (Default priority is UTILX_NOTIFICATION_LEVEL_LOW) + * + * The priority is used for ordering of notification windows.\n + * The notification window which is set UTILX_NOTIFICATION_LEVEL_HIGH priority will be placed to the top of notification windows.\n + * If there are notification windows that have same priorities, the latest created notification window is placed on the other window. + * + * This function is a asynchronous call. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] win Specifies the window to be set + * @param[in] level Specifies the level (UTILX_NOTIFICATION_LEVEL_LOW, UTILX_NOTIFICATION_LEVEL_NORMAL, UTILX_NOTIFICATION_LEVEL_HIGH) + * @remark This is used only notification window. + * @pre The win should be notification type window + * @post None + * @see utilx_get_system_notification_level + * @par Example + @code + #include + + ... + + Evas_Object *win; + Ecore_X_Window xwin; + + win = create_mwnd(); + xwin = elm_win_xwindow_get(win); + + // Set Notification type + ecore_x_netwm_window_type_set (xwin, ECORE_X_WINDOW_TYPE_NOTIFICATION); + + // Set Notification's priority + utilx_set_system_notification_level (ecore_x_display_get(), xwin, UTILX_NOTIFICATION_LEVEL_HIGH); + + ... + @endcode + */ +void utilx_set_system_notification_level (Display* dpy, Window win, Utilx_Notification_Level level); + +/** + * @fn Utilx_Notification_Level utilx_get_system_notification_level (Display* dpy, Window win) + * @brief Gets the priority level for the specified notification window + * + * This function returns the priority level of the notification windows.\n + * If a user didn't set the notification's priority level, this function returns default value (UTILX_NOTIFICATION_LEVEL_LOW). + * + * This function is a synchronous call. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] win Specifies the window to be get + * @return current notication level (UTILX_NOTIFICATION_LEVEL_LOW, UTILX_NOTIFICATION_LEVEL_NORMAL, UTILX_NOTIFICATION_LEVEL_HIGH) + * @remark This is used only notification window. + * @pre The win should be notification type window + * @post None + * @see utilx_set_system_notification_level + * @par Example + @code + #include + + ... + + Evas_Object *win; + Ecore_X_Window xwin; + Utilx_Notification_Level level; + + win = elm_win_add (NULL, "test", ELM_WIN_NOTIFICATION); + xwin = elm_win_xwindow_get(win); + + level = utilx_get_system_notification_level (ecore_x_display_get(), xwin); + + ... + @endcode + */ +Utilx_Notification_Level utilx_get_system_notification_level (Display* dpy, Window win); + +/** + * @fn void utilx_enable_indicator (Display* dpy, Window win, int enable) + * @brief Sets the window to show/hide the indicator + * + * This function enables or disables the indicator. + * + * If an application wants to show the window with the indicator, the application must call this function with 1 as the enable parameter.\n + * Otherwise, the application must call this function with 0 as the enable parameter. + * + * This function is a asynchronous call. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] win Specifies the window to use indicator + * @param[in] enable Specifies whether the window use indicator or not + * @remark None + * @pre None + * @post If the enable is 1, then the indicator window should be shown on the screen. Otherwise, the indicator window should be hidden from the screen. + * @see elm_win_indicator_state_set, utilx_get_indicator_state + * @par Example + @code + #include + #include + + ... + + Display* dpy; + Window root, win; + + dpy = XOpenDisplay (NULL); + root = XDefaultRootWindow (dpy); + + win = XCreateSimpleWindow (dpy, root, 0, 0, 480, 800, 2, BlackPixel (dpy,0), WhitePixel(dpy,0)); + XMapWindow (dpy, win); + + // If the win want to show indicator, enables indicator. + utilx_enable_indicator (dpy, win, 1); + XFlush (d); + + // If the win want to hide indicator, disables indicator. + utilx_enable_indicator (dpy, win, 0); + XFlush (d); + + ... + @endcode + */ +void utilx_enable_indicator (Display* dpy, Window win, int enable); + +/** + * @fn int utilx_get_indicator_state (Display* dpy, Window win) + * @brief Gets the indicator's state of the specified window + * + * This function gets the indicator's state of the specified window. + * + * An application can set the indicator's state using utilx_enable_indicator or elm_win_indicator_state_set. + * If an application sets enables the indicator, this returns 1.\n + * If an application disables the indicator, this returns 0.\n + * If an application doesn't set the indicator's state, in other words, + * an application doesn't call utilx_enable_indicator or elm_win_indicator_state_set, + * this returns -1. + * + * This function is a asynchronous call. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] win Specifies the window to get the indicator's state + * @return 1 if the indicator is enabled, 0 if the indicator is disabled, otherwise -1 + * @remark None + * @pre None + * @post None + * @see elm_win_indicator_state_set, utilx_enable_indicator + * @par Example + @code + #include + #include + + ... + + Display* dpy; + Window root, win; + int state; + + dpy = XOpenDisplay (NULL); + root = XDefaultRootWindow (dpy); + + win = XCreateSimpleWindow (dpy, root, 0, 0, 480, 800, 2, BlackPixel (dpy,0), WhitePixel(dpy,0)); + XMapWindow (dpy, win); + + state = utilx_get_indicator_state (dpy, win) + // state is -1 (unknown) + + // If the win want to show indicator, enables indicator. + utilx_enable_indicator (dpy, win, 1); + XFlush (d); + + state = utilx_get_indicator_state (dpy, win) + // state is 1 (enabled) + + // If the win want to hide indicator, disables indicator. + utilx_enable_indicator (dpy, win, 0); + XFlush (d); + + state = utilx_get_indicator_state (dpy, win) + // state is 0 (disabled) + + ... + @endcode + */ +int utilx_get_indicator_state (Display* dpy, Window win); + + +/** + * @fn int utilx_grab_key (Display* dpy, Window win, const char* key_name, int grab_mode) + * @brief Grabs a key specfied by key_name for win in grab_mode + * + * This function establishs a grab of the specified key for the specified window.\n + * Once a key was grabbed, all events originated from the key will only be reported to the specfied window.\n + * The grab of the key will be released by calling utilx_ungrab_key. + * + * This function is synchronous. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] win Specifies the window to grab a key + * @param[in] key_name Name of a key in string (ex> KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_SEND and so on) + * @param[in] grab_mode Grab mode (such as EXCLUSIVE_GRAB, TOP_POSITION_GRAB and SHARED_GRAB) + * @return 0 on Success, otherwise Fail + * @remark If utilx_grab_key() returns 0, the specified window will get the events of the specified key.\n + However, delivery of a key can always be changed by other applications grabbing the key with higher priority.\n + It can also be changed by the changes of window stacks.\n + Trial for choosing a proper grab mode will be needed. + * @pre This API must be called after the window 'win' has been mapped + * @post This API adds/changes the window property related to grabbed key + * @see utilx_ungrab_key + * @par Example (using X11 APIs) + @code + + // EXCLUSIVE_GRAB // + + #include + #include + + int main() + { + Display *disp = XOpenDisplay(NULL); + XEvent e; + int grab_result; + Window w = XCreateSimpleWindow(disp, DefaultRootWindow(disp), 5,5, 470, 780, 2, BlackPixel(d,0), WhitePixel(d,0)); + XSelectInput(disp, w, StructureNotifyMask | KeyPressMask | KeyReleaseMask); + XMapWindow(disp, w); + + while(1) + { + XNextEvent(disp, &e); + switch(e.type) + { + case MapNotify: + grab_result = utilx_grab_key(disp, w, KEY_POWER, EXCLUSIVE_GRAB); + if( EXCLUSIVE_GRABBED_ALREADY == grab_result ) + return -1; + break; + } + ... + } + ... + + utilx_ungrab_key(disp, win, KEY_POWER); + return 0; + } + + // TOP_POSITION_GRAB // + + #include + #include + + int main() + { + Display *disp = XOpenDisplay(NULL); + XEvent e; + Window w = XCreateSimpleWindow(disp, DefaultRootWindow(disp), 5,5, 470, 780, 2, BlackPixel(d,0), WhitePixel(d,0)); + XSelectInput(disp, w, StructureNotifyMask | KeyPressMask | KeyReleaseMask); + XMapWindow(disp, w); + + while(1) + { + XNextEvent(disp, &e); + switch(e.type) + { + case MapNotify: + utilx_grab_key(disp, w, KEY_POWER, TOP_POSITION_GRAB); + break; + } + ... + } + ... + + utilx_ungrab_key(disp, win, KEY_POWER); + return 0; + } + + // SHARED_GRAB // + + #include + #include + + int main() + { + Display *disp = XOpenDisplay(NULL); + XEvent e; + Window w = XCreateSimpleWindow(disp, DefaultRootWindow(disp), 5,5, 470, 780, 2, BlackPixel(d,0), WhitePixel(d,0)); + XSelectInput(disp, w, StructureNotifyMask | KeyPressMask | KeyReleaseMask); + XMapWindow(disp, w); + + while(1) + { + XNextEvent(disp, &e); + switch(e.type) + { + case MapNotify: + utilx_grab_key(disp, w, KEY_POWER, SHARED_GRAB); + break; + } + ... + } + ... + + utilx_ungrab_key(disp, win, KEY_POWER); + return 0; + } + + @endcode + * @par Example (using EFL APIs) + @code + + // EXCLUSIVE_GRAB // + + #include + #include + #include + + int main() + { + ... + + Ecore_X_Display* disp = ecore_x_display_get(); + Ecore_X_Window win = ecore_evas_software_x11_window_get(ee); + + int grab_result = utilx_grab_key(disp, win, KEY_POWER, EXCLUSIVE_GRAB); + if( EXCLUSIVE_GRABBED_ALREADY == grab_result ) + return -1; + + ... + + utilx_ungrab_key(disp, win, KEY_POWER);//Ungrab whenever you want to ¡¦ + return 0; + } + + // TOP_POSITION_GRAB // + + #include + #include + #include + + int main() + { + ... + + Ecore_X_Display* disp = ecore_x_display_get(); + Ecore_X_Window win = ecore_evas_software_x11_window_get(ee); + + utilx_grab_key(disp, win, KEY_POWER, TOP_POSITION_GRAB); + + ... + + utilx_ungrab_key(disp, win, KEY_POWER);//Ungrab whenever you want to ¡¦ + return 0; + } + + // SHARED_GRAB // + + #include + #include + #include + + int main() + { + ... + + Ecore_X_Display* disp = ecore_x_display_get(); + Ecore_X_Window win = ecore_evas_software_x11_window_get(ee); + + utilx_grab_key(disp, win, KEY_POWER, SHARED_GRAB); + + ... + + utilx_ungrab_key(disp, win, KEY_POWER);//Ungrab whenever you want to ¡¦ + return 0; + } + @endcode + */ +int utilx_grab_key (Display* dpy, Window win, const char* key_name, int grab_mode); + +/** + * @fn int utilx_ungrab_key (Display* dpy, Window win, const char* key_name) + * @brief Ungrabs a key specfied by key_name for win + * + * This function releases the already established grab of the specfied key for the specified window.\n + * Once the grab of the key was released, delivery of the key events for the specfied window is going to be stopped. + * + * This function is synchronous. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] win Specifies the window to grab a key + * @param[in] key_name Name of a key in string (ex> KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_SEND and so on) + * @return 0 on Success, otherwise Fail + * @remark No additional information + * @pre This API must be called after the window 'win' has been mapped + * @post This API changes/removes the window property related to grabbed key + * @see utilx_grab_key + * @par Example (using X11 APIs) + @code + + // EXCLUSIVE_GRAB // + + #include + #include + + int main() + { + Display *disp = XOpenDisplay(NULL); + XEvent e; + int grab_result; + Window w = XCreateSimpleWindow(disp, DefaultRootWindow(disp), 5,5, 470, 780, 2, BlackPixel(d,0), WhitePixel(d,0)); + XSelectInput(disp, w, StructureNotifyMask | KeyPressMask | KeyReleaseMask); + XMapWindow(disp, w); + + while(1) + { + XNextEvent(disp, &e); + switch(e.type) + { + case MapNotify: + grab_result = utilx_grab_key(disp, w, KEY_POWER, EXCLUSIVE_GRAB); + if( EXCLUSIVE_GRABBED_ALREADY == grab_result ) + return -1; + break; + } + ... + } + ... + + utilx_ungrab_key(disp, win, KEY_POWER); + return 0; + } + + // TOP_POSITION_GRAB // + + #include + #include + + int main() + { + Display *disp = XOpenDisplay(NULL); + XEvent e; + Window w = XCreateSimpleWindow(disp, DefaultRootWindow(disp), 5,5, 470, 780, 2, BlackPixel(d,0), WhitePixel(d,0)); + XSelectInput(disp, w, StructureNotifyMask | KeyPressMask | KeyReleaseMask); + XMapWindow(disp, w); + + while(1) + { + XNextEvent(disp, &e); + switch(e.type) + { + case MapNotify: + utilx_grab_key(disp, w, KEY_POWER, TOP_POSITION_GRAB); + break; + } + ... + } + ... + + utilx_ungrab_key(disp, win, KEY_POWER); + return 0; + } + + // SHARED_GRAB // + + #include + #include + + int main() + { + Display *disp = XOpenDisplay(NULL); + XEvent e; + Window w = XCreateSimpleWindow(disp, DefaultRootWindow(disp), 5,5, 470, 780, 2, BlackPixel(d,0), WhitePixel(d,0)); + XSelectInput(disp, w, StructureNotifyMask | KeyPressMask | KeyReleaseMask); + XMapWindow(disp, w); + + while(1) + { + XNextEvent(disp, &e); + switch(e.type) + { + case MapNotify: + utilx_grab_key(disp, w, KEY_POWER, SHARED_GRAB); + break; + } + ... + } + ... + + utilx_ungrab_key(disp, win, KEY_POWER); + return 0; + } + + @endcode + * @par Example (using EFL APIs) + @code + + // EXCLUSIVE_GRAB // + + #include + #include + #include + + int main() + { + ... + + Ecore_X_Display* disp = ecore_x_display_get(); + Ecore_X_Window win = ecore_evas_software_x11_window_get(ee); + + int grab_result = utilx_grab_key(disp, win, KEY_POWER, EXCLUSIVE_GRAB); + if( EXCLUSIVE_GRABBED_ALREADY == grab_result ) + return -1; + ... + + utilx_ungrab_key(disp, win, KEY_POWER);//Ungrab whenever you want to ¡¦ + return 0; + } + + // TOP_POSITION_GRAB // + + #include + #include + #include + + int main() + { + ... + + Ecore_X_Display* disp = ecore_x_display_get(); + Ecore_X_Window win = ecore_evas_software_x11_window_get(ee); + + utilx_grab_key(disp, win, KEY_POWER, TOP_POSITION_GRAB); + + ... + + utilx_ungrab_key(disp, win, KEY_POWER);//Ungrab whenever you want to ¡¦ + + return 0; + } + + // SHARED_GRAB // + + #include + #include + #include + + int main() + { + ... + + Ecore_X_Display* disp = ecore_x_display_get(); + Ecore_X_Window win = ecore_evas_software_x11_window_get(ee); + + utilx_grab_key(disp, win, KEY_POWER, SHARED_GRAB); + + ... + + utilx_ungrab_key(disp, win, KEY_POWER);//Ungrab whenever you want to ¡¦ + return 0; + } + @endcode + */ +int utilx_ungrab_key (Display* dpy, Window win, const char* key_name); + +/** + * @fn int utilx_get_key_status(Display* dpy, char *key_name) + * @brief Gets a status of a key specified by key_name + * + * This function gets a status of a key.\n + * ex>UTILX_KEY_STATUS_PRESSED, UTILX_KEY_STATUS_RELEASED and UTILX_KEY_STATUS_UNKNOWN + * + * This function is synchronous. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] key_name Name of a key in string (ex> KEY_VOLUMEUP, KEY_VOLUMEDOWN, KEY_SEND and so on) + * @return 0 on Success, otherwise Fail + * @remark No additional information + * @pre This API must be called for H/W keys specified in this header file(utilX.h). + * @par Example (using X11 APIs) + @code + + #include + #include + + int main() + { + Display *disp = XOpenDisplay(NULL); + Utilx_Key_Status status; + + status = utilx_get_key_status(disp, KEY_PLAYCD); + + switch( status ) + { + case UTILX_KEY_STATUS_PRESSED: + //The key is pressed. + break; + + case UTILX_KEY_STATUS_RELEASED: + //The key is released. + break; + + case UTILX_KEY_STATUS_UNKNOWN: + default: + //The key status is unknown; + break; + } + + return 0; + } + + @endcode + * @par Example (using EFL APIs) + @code + + #include + #include + #include + + int main() + { + ... + + Ecore_X_Display* disp = ecore_x_display_get(); + Utilx_Key_Status status; + + status = utilx_get_key_status(disp, KEY_PLAYCD); + + switch( status ) + { + case UTILX_KEY_STATUS_PRESSED: + //The key is pressed. + break; + + case UTILX_KEY_STATUS_RELEASED: + //The key is released. + break; + + case UTILX_KEY_STATUS_UNKNOWN: + default: + //The key status is unknown; + break; + } + return 0; + } + @endcode + */ +Utilx_Key_Status utilx_get_key_status(Display* dpy, char *key_name); + +/* Window Effect APIs */ +/** + * @fn void utilx_set_window_effect_state(Display* dpy, Window win, int state) + * @brief Sets a window's effect state ( enable or disable ) + * + * This function sets window's effect state. if effect is not enabled by composite manager, \n + * window's effect could not be enabled. + * + * This function is a asynchronous call. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] win Specifies the window handle + * @param[in] state Enables/disables the window effect + * @remark This is used only client window. ( not root window ) + * @pre This api must be called before fist show ( XMapWindow Event ). + * @post This changes Client Window's Effect related property. + * @see utilx_get_window_effect_state + * @par Example + @code + #include + #include + ... + + Display* dpy; + Window root, win; + + dpy = XOpenDisplay (NULL); + root = XDefaultRootWindow (dpy); + + win = XCreateSimpleWindow (dpy, root, 0, 0, 480, 800, 2, BlackPixel (dpy,0), WhitePixel(dpy,0)); + + // Sets a window's effect state to enable ( enable : 1, disable 0 ) + utilx_set_window_effect_state(dpy, win, 1); + + XMapWindow (dpy, win); + ... + @endcode + */ +void utilx_set_window_effect_state(Display* dpy, Window win, int state); + +/** +* @fn int utilx_get_window_effect_state(Display* dpy, Window win) +* @brief Gets a window's effect state ( enable or disable ) +* +* This function returns windows's effect state.\n +* If effect is not enabled by composite manager, then this return value is unusable or meanless. +* +* This function is a asynchronous call. +* +* @param[in] dpy Specifies the connection to the X server +* @param[in] win Specifies the window handle +* @return Current window effect state +* @remark This is used only client window. ( not root window ) +* @pre This api does not require any pre-condition. +* @post This api does not change any condition. +* @see utilx_set_window_effect_state +* @par Example + @code + #include + #include + ... + + Display* dpy; + Window root, win; + + dpy = XOpenDisplay (NULL); + root = XDefaultRootWindow (dpy); + + win = XCreateSimpleWindow (dpy, root, 0, 0, 480, 800, 2, BlackPixel (dpy,0), WhitePixel(dpy,0)); + + XMapWindow (dpy, win); + + // Gets a window's effect state ( enable : 1, disable 0 ) + printf( "current window's effect state = %d\n", utilx_get_window_effect_state(dpy, win) ) ; + ... + @endcode +*/ +int utilx_get_window_effect_state(Display* dpy, Window win); + +/** + * @fn void utilx_show_fake_effect(Display* dpy, Window win, char *fake_image_file) + * @brief Shows a window's "fake show effect" animation + * + * This function show's application fake show image.\n + * This function is only used by application launching program. + * + * This function is a asynchronous call. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] win Specifies the root window handle + * @param[in] fake_image_file Specifies the fake window image and file format is png type. + * @remark This is used only menu-screen window. + * @pre This api must be called before client's fist show ( XMapWindow Event ). you must call this api then run application. + * @post This changes root window's fake effect related property. + * @see utilx_hide_fake_effect + * @par Example + @code + #include + #include + ... + + Display* dpy; + Window root; + + dpy = XOpenDisplay (NULL); + root = XDefaultRootWindow (dpy); + + // Shows a window's "fake show effect" animation, and if you want to see animation, /root/fake_window_image.png file must be exited. + utilx_show_fake_effect( dpy, root, "/root/fake_window_image.png"); + ... + @endcode + */ +void utilx_show_fake_effect(Display *dpy, Window win, char *fake_image_file); + +/** + * @fn void utilx_hide_fake_effect(Display* dpy, Window win) + * @brief Shows a window's "fake hide effect" animation, and this animation uses "fake show effect" 's window image. + * + * This function shoes a window's fake hide effect.\n + * This function is only used by application launching program.\n + * When application was not executed by any error. + * + * This function is a asynchronous call. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] win Specifies the root window handle + * @remark This is used only menu-screen window. + * @pre This api must be called after "utilx_show_fake_effect()". + * @post This changes root window's fake effect related property. + * @see utilx_show_fake_effect + * @par Example + @code + #include + #include + ... + + Display* dpy; + Window root; + + dpy = XOpenDisplay (NULL); + root = XDefaultRootWindow (dpy); + + // Shows a window's "fake hide effect" animation. and if you wnat to see animation, utilx_show_fake_effect() function must be excuted before utilx_show_fake_effect() + // and if real window is showed , then fake hide effect could not be showed. + utilx_hide_fake_effect( dpy, root ); + ... + @endcode + */ +void utilx_hide_fake_effect(Display *dpy, Window win); + +/** + * @fn void utilx_set_window_effect_style(Display* dpy, Window win, Utilx_Effect_Type type, Utilx_Effect_Style style) + * @brief Sets a window's effect style with effect type. + * + * This function sets a window's effect style with effect type.\n + * Default Window Effect is setted by Window Type and Window Class.\n + * And then, you could change custom effecct.\n + * Custom Effect is available max 10. ( CUSTOM0 ~ CUSTOM9 )\n + * If you didn't set custom effect, then compositing window manger provides Default Window Effect.\n + * + * This function is a asynchronous call. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] win Specifies the window handle + * @param[in] type Specifies the window's effect type ( ex. UTILX_EFFECT_TYPE_MAP, UTILX_EFFECT_TYPE_UNMAP, etc ) + * @param[in] style Specifies the window's effect style ( ex. UTILX_EFFECT_STYLE_DEFAULT, UTILX_EFFECT_STYLE_NONE, UTILX_EFFECT_STYLE_CUSTOM0, etc ) + * @remark This is used only client window. ( not root window ) + * @pre This api does not require any pre-condition. + * @post This changes window's effect type related property ( _NET_CM_WINDOW_EFFECT_TYPE ). + * @see utilx_get_window_effect_style + * @par Example + @code + #include + #include + #include + ... + + Display *dpy ; + Window win, root ; + unsigned long black, white; + + dpy = XOpenDisplay(NULL) ; + + black = BlackPixel(dpy, 0); + white = WhitePixel(dpy, 0); + + root = XDefaultRootWindow (dpy); + win = XCreateSimpleWindow ( dpy, root, 0, 0, 100, 100, 2, BlackPixel (d,0), WhitePixel(d,0) ); + + utilx_set_window_effect_style(dpy, win, UTILX_EFFECT_TYPE_MAP, UTILX_EFFECT_STYLE_CUSTOM0); // window's show effet type change to UTILX_EFFECT_STYLE_CUSTOM0 + + XMapWindow(dpy, win); + + ... + + utilx_set_window_effect_style(dpy, win, UTILX_EFFECT_TYPE_UNMAP, UTILX_EFFECT_STYLE_CUSTOM0); // window's hide effet type change to UTILX_EFFECT_STYLE_CUSTOM0 + + XUnmapWindow (dpy, win); + + utilx_set_window_effect_style(dpy, win, UTILX_EFFECT_TYPE_MAP, UTILX_EFFECT_STYLE_DEFAULT); // window's show effet type change to UTILX_EFFECT_STYLE_DEFAULT + XMapWindow (dpy, win); + + ... + + utilx_set_window_effect_style(dpy, win, UTILX_EFFECT_TYPE_UNMAP, UTILX_EFFECT_STYLE_DEFAULT); // window's hide effet type change to UTILX_EFFECT_STYLE_DEFAULT + XUnmapWindow (dpy, win); + + ... + + utilx_set_window_effect_style(dpy, win, UTILX_EFFECT_TYPE_MAP, UTILX_EFFECT_STYLE_NONE); // window's show effet type change to UTILX_EFFECT_STYLE_NONE + XMapWindow (dpy, win); + + ... + + utilx_set_window_effect_style(dpy, win, UTILX_EFFECT_TYPE_UNMAP, UTILX_EFFECT_STYLE_NONE); // window's hide effet type change to UTILX_EFFECT_STYLE_NONE + XUnmapWindow (dpy, win); + + ... + @endcode + */ +void utilx_set_window_effect_style(Display* dpy, Window win, Utilx_Effect_Type type, Utilx_Effect_Style style); + +/** + * @fn Utilx_Effect_Style utilx_get_window_effect_style(Display* dpy, Window win, Utilx_Effect_Type type) + * @brief Gets a window's effect style with effect type. + * + * This function gets a window's effect style with effect type.\n + * + * This function is a asynchronous call. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] win Specifies the window handle + * @param[in] type Specifies the window's effect type ( ex. UTILX_EFFECT_TYPE_MAP, UTILX_EFFECT_TYPE_UNMAP, etc ) + * @return Current window's effect style ( ex. UTILX_EFFECT_STYLE_DEFAULT, UTILX_EFFECT_STYLE_NONE, UTILX_EFFECT_STYLE_CUSTOM0, etc ) + * @remark This is used only client window. ( not root window ) + * @pre This api does not require any pre-condition. + * @post This api does not change any condition. + * @see utilx_set_window_effect_style + * @par Example + @code + #include + #include + #include + ... + + Display *dpy ; + Window win, root ; + unsigned long black, white; + Utilx_Effect_Style style; + + dpy = XOpenDisplay(NULL) ; + + black = BlackPixel(dpy, 0); + white = WhitePixel(dpy, 0); + + root = XDefaultRootWindow (dpy); + win = XCreateSimpleWindow ( dpy, root, 0, 0, 100, 100, 2, BlackPixel (d,0), WhitePixel(d,0) ); + + style = utilx_set_window_effect_style(dpy, win, UTILX_EFFECT_TYPE_MAP); // get effect style with window's show effet type + + ... + + style = utilx_set_window_effect_style(dpy, win, UTILX_EFFECT_TYPE_UNMAP); // get effect style with window's show effet type + + ... + @endcode + */ +Utilx_Effect_Style utilx_get_window_effect_style(Display* dpy, Window win, Utilx_Effect_Type type); + +/** + * @fn void utilx_set_window_opaque_state (Display* dpy, Window win, int opaque) + * @brief Sets the window's opaque state + * + * This function sets window's visibility to opaque even if the window is an alpha window. + * This function is available only alpha window. + * An alpha window's default opaque state is UTILX_OPAQUE_STATE_OFF. + * + * This function is a asynchronous call. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] win Specifies the window handle + * @param[in] state Specifies whether the window set a visible state to opaque(UTILX_OPAQUE_STATE_ON) or not(UTILX_OPAQUE_STATE_OFF) + * @return 1 on Success, otherwise Fail + * @remark This is used only alpha window. + * @pre None + * @post + * @see + * @par Example + @code + #include + #include + + ... + + Display* dpy; + Window root, win; + int ret; + + dpy = XOpenDisplay (NULL); + root = XDefaultRootWindow (dpy); + + win = XCreateSimpleWindow (dpy, root, 0, 0, 480, 800, 2, BlackPixel (dpy,0), WhitePixel(dpy,0)); + XMapWindow (dpy, win); + + ret = utilx_set_window_opaque_state (dpy, win, UTILX_OPAQUE_STATE_ON); + if (!ret) + { + printf ("Error! Failed to set opaque state.\n"); + } + + XFlush (dpy); + + ... + @endcode + */ +int utilx_set_window_opaque_state (Display* dpy, Window win, Utilx_Opaque_State state); + +/** + * @fn int utilx_set_screen_capture(Display* dpy, int enable) + * @brief Specifies whether the screen capture functionality is enable or not. + * + * This function makes the screen capture functionality of CBHM enable or disable. + * CBHM = Clipboard History Manager. + * + * This function is synchronous. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] enable Specifies the window handle. (1:Enable, 0:Disable) + * @pre This api does not require any pre-condition. + * @post This api does not change any condition. + * @see utilx_get_screen_capture + * @par Example + @code + #include + #include + #include + ... + + Display *dpy ; + + dpy = XOpenDisplay(NULL) ; + + utilx_set_screen_capture (dpy, 1); + + ... + @endcode + */ +int utilx_set_screen_capture(Display* dpy, int enable); + +/** + * @fn int utilx_get_screen_capture(Display* dpy, int enable) + * @brief Gets whether the screen capture functionality is enable or not. + * + * This function gets whether the screen capture functionality of CBHM is enable or not. + * CBHM = Clipboard History Manager. + * + * This function is synchronous. + * + * @param[in] dpy Specifies the connection to the X server + * @pre This api does not require any pre-condition. + * @post This api does not change any condition. + * @see utilx_set_screen_capture + * @par Example + @code + #include + #include + #include + ... + + Display *dpy ; + int enable; + + dpy = XOpenDisplay(NULL) ; + + enable = utilx_set_screen_capture (dpy); + + ... + @endcode + */ +int utilx_get_screen_capture(Display* dpy); + +/** + * @fn void utilx_set_window_cardinal_property(Display* dpy, Window win, Atom atom, unsigned int *value) + * @brief Sets the cardinal property to Window + * + * This function Sets the cardinal property to Window. + * + * This function is synchronous. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] win Specifies the window handle + * @param[in] atom Specifies the atom of cardinal property + * @param[in] value the value of cardinal property to set. + * @pre This api does not require any pre-condition. + * @post This api does not change any condition. + * @see utilx_get_window_cardinal_property + * @par Example + @code + #include + #include + #include + ... + + Display *dpy ; + Window root; + Atom atom = None; + int value = 1; + + dpy = XOpenDisplay (NULL); + root = XDefaultRootWindow (dpy); + + atom = XInternAtom(dpy, "TEST_ATOM", False); + + utilx_set_window_cardinal_property (dpy, root, atom, (unsigned int*)&value); + + ... + @endcode + */ +void utilx_set_window_cardinal_property(Display* dpy, Window win, Atom atom, unsigned int *value); + +/** + * @fn int utilx_get_window_cardinal_property(Display* dpy, Window win, Atom atom, unsigned int *value) + * @brief Gets the value of cardinal property. + * + * This function gets the value of cardinal property. + * + * This function is synchronous. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] win Specifies the window handle + * @param[in] atom Specifies the atom of cardinal property + * @param[out] value the value of cardinal property to get. + * @pre This api does not require any pre-condition. + * @post This api does not change any condition. + * @see utilx_set_window_cardinal_property + * @par Example + @code + #include + #include + #include + ... + + Display *dpy ; + Window root; + Atom atom = None; + int value; + + dpy = XOpenDisplay (NULL); + root = XDefaultRootWindow (dpy); + + atom = XInternAtom(dpy, "TEST_ATOM", False); + + if (utilx_set_window_cardinal_property (dpy, root, atom, (unsigned int*)&value) > 0) + { + success; + } + + ... + @endcode + */ +int utilx_get_window_cardinal_property(Display* dpy, Window win, Atom atom, unsigned int *value); + +/** + * @fn void utilx_show_capture_effect(Display *dpy, Window win ) + * @brief Shows a capture effect animation + * + * This function show capture effect animation.\n + * This function is only used by Screen Capture Application. + * + * This function is a asynchronous call. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] win Specifies the root window handle + * @remark This is used only screen capture application. + * @pre This api does not require any pre-condition. + * @post This api does not change any condition. + * @see utilx_set_screen_capture + * @par Example + @code + #include + #include + ... + + Display* dpy; + Window root; + + dpy = XOpenDisplay (NULL); + root = XDefaultRootWindow (dpy); + + // Shows a Shows a capture effect animation + utilx_show_capture_effect( dpy, root); + ... + @endcode + */ +void utilx_show_capture_effect(Display *dpy, Window win ); + +/** + * @fn void* utilx_create_screen_shot (Display* dpy, int width, int height) + * @brief Create a screenshot image. + * + * This function create a screenshot image.\n + * To use this function, you should get the permission first. Once this functions + * is called, utilx_release_screen_shot should be called after it. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] width Specifies the root window handle + * @param[in] height Specifies the root window handle + * @remark You should get the permission to use. + * @post This api does not change any condition. + * @see utilx_release_screen_shot + * @par Example + @code + Display* dpy; + int width, height; + void *dump; + + dpy = XOpenDisplay (NULL); + width = DisplayWidth (dpy, DefaultScreen (dpy)); + height = DisplayHeight (dpy, DefaultScreen (dpy)); + + dump = utilx_create_screen_shot (dpy, width, height); + if (dump) + { + // do_something (dump); + } + else + { + // utilx_create_screen_shot can return NULL in some cases. + // Even if it returns NULL, utilx_release_screen_shot should be called. + } + + utilx_release_screen_shot (); + @endcode + */ +void* utilx_create_screen_shot (Display* dpy, int width, int height); + +/** + * @fn void utilx_release_screen_shot (void) + * @brief Release screenshot resources. + * + * This function release screenshot resources.\n + * utilx_release_screen_shot should be called once utilx_create_screen_shot is + * called. + * + * @see utilx_create_screen_shot + * @par Example + @code + Display* dpy; + int width, height; + void *dump; + + dpy = XOpenDisplay (NULL); + width = DisplayWidth (dpy, DefaultScreen (dpy)); + height = DisplayHeight (dpy, DefaultScreen (dpy)); + + dump = utilx_create_screen_shot (dpy, width, height); + if (dump) + { + // do_something (dump); + } + else + { + // utilx_create_screen_shot can return NULL in some cases. + // Even if it returns NULL, utilx_release_screen_shot should be called. + } + + utilx_release_screen_shot (); + @endcode + */ +void utilx_release_screen_shot (void); + +/** + * @fn void utilx_set_fb_visible (Display* dpy, Utilx_Fb_Type fb_type, Bool visible) + * @brief Set fb's visibility. + * + * This function can make a framebuffer visible or non-visible. \n + * By the way, in case of UTILX_FB_TYPE_UI, if there is the request for UI update, + * the visibility of UI framebuffer will be changed from False to True automatically. + * Please note this. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] fb_type Specifies the fb type to set visibility of a framebuffer + * @param[in] visible Visible/Non-Visible + * @see utilx_get_fb_visible + * @par Example + @code + #include + ... + Display* dpy = XOpenDisplay (NULL); + + // Hide the UI framebuffer of main lcd. + utilx_set_fb_visible (dpy, UTILX_FB_TYPE_UI, False); + ... + @endcode + */ +void utilx_set_fb_visible (Display* dpy, Utilx_Fb_Type fb_type, Bool visible); + +/** + * @fn Bool utilx_get_fb_visible (Display* dpy, Utilx_Fb_Type fb_type) + * @brief Get framebuffer's visibility. + * + * This function get the visibility of a framebuffer. \n + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] fb_type Specifies the fb type to get visibility of a framebuffer + * @return Current visibility of a framebuffer + * @see utilx_set_fb_visible + * @par Example + @code + #include + ... + Display* dpy = XOpenDisplay (NULL); + Bool visible; + + visible = utilx_get_fb_visible (dpy, UTILX_FB_TYPE_UI); + ... + @endcode + */ +Bool utilx_get_fb_visible (Display* dpy, Utilx_Fb_Type fb_type); + +/** + * @fn void utilx_set_video_offset (Display* dpy, int x, int y) + * @brief Set the offset of video. + * + * This function sets the offset of video layer. \n + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] x x offset + * @param[in] y y offset + * @par Example + @code + #include + ... + Display* dpy = XOpenDisplay (NULL); + + utilx_set_video_offset (dpy, 0, 100); + ... + @endcode + */ +void utilx_set_video_offset (Display* dpy, int x, int y); + +#ifdef __cplusplus +} +#endif + + +/** + * @} + */ + +#endif /* __SAMSUNG_LINUX_UTIL_X11_H__ */ + diff --git a/utilX.pc b/utilX.pc new file mode 100644 index 0000000..f0fd703 --- /dev/null +++ b/utilX.pc @@ -0,0 +1,12 @@ +# Package Information for pkg-config + +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: libSLP-utilX +Description: SAMSUNG Linux platform X11 utilities library +Version: 1.1.0 +Libs: -L${libdir} -lutilX +Cflags: -I${includedir} diff --git a/utilX.pc.in b/utilX.pc.in new file mode 100644 index 0000000..5079edf --- /dev/null +++ b/utilX.pc.in @@ -0,0 +1,12 @@ +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: libSLP-utilX +Description: SAMSUNG Linux platform X11 utilities library +Version: @VERSION@ +Libs: -L${libdir} -lutilX +Cflags: -I${includedir} diff --git a/util_x11.h b/util_x11.h new file mode 100644 index 0000000..a1a3c3f --- /dev/null +++ b/util_x11.h @@ -0,0 +1,27 @@ +/* + * libslp-utilx + * + Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + * + */ + +#ifndef __SAMSUNG_LINUX_UTIL_X11_I_H__ +#define __SAMSUNG_LINUX_UTIL_X11_I_H__ + +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + +#endif /* __SAMSUNG_LINUX_APP_UTIL_X11_IH__ */ diff --git a/x11.c b/x11.c new file mode 100644 index 0000000..34496f7 --- /dev/null +++ b/x11.c @@ -0,0 +1,2144 @@ +/* + * libslp-utilx + * + Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "utilX.h" +#include "util_x11.h" + +#include +#include +#include +#include +#include +#include +#include + + +#define UTILX_DEBUG 0 +#if UTILX_DEBUG +#define UTILX_TRACE printf +#else +#define UTILX_TRACE(...) +#endif + +static Atom _atom_grab_key = None; +static Atom _atom_grab_excl_win = None; +static Atom _atom_grab_or_excl_win = None; + +static Atom _atom_notification_level = None; +static Atom _atom_indicator_visible_state = None; +static Atom _atom_indicator_visible_state_on = None; +static Atom _atom_indicator_visible_state_off = None; + +static Atom _atom_comp_effect_state = None; +static Atom _atom_comp_fake_launch = None; +static Atom _atom_comp_fake_launch_image = None; + +static Atom _atom_comp_window_effect_type = None; +static Atom _atom_comp_effect_default = None; +static Atom _atom_comp_effect_none = None; +static Atom _atom_comp_effect_custom0 = None; +static Atom _atom_comp_effect_custom1 = None; +static Atom _atom_comp_effect_custom2 = None; +static Atom _atom_comp_effect_custom3 = None; +static Atom _atom_comp_effect_custom4 = None; +static Atom _atom_comp_effect_custom5 = None; +static Atom _atom_comp_effect_custom6 = None; +static Atom _atom_comp_effect_custom7 = None; +static Atom _atom_comp_effect_custom8 = None; +static Atom _atom_comp_effect_custom9 = None; + +static Atom _atom_window_opaque = None; + +static Atom _atom_screen_capture_disable = None; + +static Atom _atom_comp_capture_effect = None; + +const unsigned long maxlen = 1024l; + +static void _utilx_set_window_property (Display* dpy, Window win, Atom atom, Atom type, unsigned int *val, unsigned int num); +static int _utilx_get_window_property (Display* dpy, Window win, Atom atom, Atom type, unsigned int *val, unsigned int len); + +static void _utilx_effect_atom_check( Display* dpy ); +static Atom _utilx_convert_style_to_atom( Display* dpy, Utilx_Effect_Style style ); +static Utilx_Effect_Style _utilx_convert_atom_to_style( Display* dpy, Atom style ); + +static int _utilx_get_indicator_atoms(Display *dpy); + +API void utilx_set_system_notification_level (Display* dpy, Window win, Utilx_Notification_Level level) +{ + UTILX_TRACE ("[UTILX] utilx_set_system_notification_level... win = %x, level = %d\n", win, level); + + int noti_level; + + if (dpy == NULL) + { + fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__); + return; + } + + switch (level) + { + case UTILX_NOTIFICATION_LEVEL_LOW: + noti_level = 50; + break; + + case UTILX_NOTIFICATION_LEVEL_NORMAL: + noti_level = 100; + break; + + case UTILX_NOTIFICATION_LEVEL_HIGH: + noti_level = 150; + break; + + default: + noti_level = 50; + break; + } + + if (!_atom_notification_level) + { + _atom_notification_level = XInternAtom (dpy, "_E_ILLUME_NOTIFICATION_LEVEL", False); + if (!_atom_notification_level) + { + fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_NOTIFICATION_LEVEL atom.. %s (%d)\n", __func__, __LINE__); + return; + } + } + + _utilx_set_window_property (dpy, win, _atom_notification_level, XA_CARDINAL, + (unsigned int *)¬i_level, 1); +} + + +API Utilx_Notification_Level utilx_get_system_notification_level (Display* dpy, Window win) +{ + UTILX_TRACE ("[UTILX] utilx_get_system_notification_level... win = %x\n", win); + + Utilx_Notification_Level noti_level; + unsigned int level; + int ret; + + noti_level = UTILX_NOTIFICATION_LEVEL_LOW; + + if (dpy == NULL) + { + fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__); + goto error; + } + + if (!_atom_notification_level) + { + _atom_notification_level = XInternAtom (dpy, "_E_ILLUME_NOTIFICATION_LEVEL", False); + if (!_atom_notification_level) + { + fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_NOTIFICATION_LEVEL atom.. %s (%d)\n", __func__, __LINE__); + goto error; + } + } + + ret = _utilx_get_window_property (dpy, win, _atom_notification_level, XA_CARDINAL, + (unsigned int *)&level, 1); + + if (ret > 0) + { + switch (level) + { + case 50: + noti_level = UTILX_NOTIFICATION_LEVEL_LOW; + break; + + case 100: + noti_level = UTILX_NOTIFICATION_LEVEL_NORMAL; + break; + + case 150: + noti_level = UTILX_NOTIFICATION_LEVEL_HIGH; + break; + + default: + noti_level = UTILX_NOTIFICATION_LEVEL_LOW; + break; + } + } + else + { + noti_level = UTILX_NOTIFICATION_LEVEL_LOW; + } + +error: + return noti_level; +} + +static int _utilx_get_indicator_atoms(Display *dpy) +{ + if (!_atom_indicator_visible_state) + { + _atom_indicator_visible_state = XInternAtom (dpy, "_E_ILLUME_INDICATOR_STATE", False); + if (!_atom_indicator_visible_state) + { + fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_INDICATOR_STATE atom.. %s (%d)\n", __func__, __LINE__); + return 0; + } + } + + if (!_atom_indicator_visible_state_on) + { + _atom_indicator_visible_state_on = XInternAtom (dpy, "_E_ILLUME_INDICATOR_ON", False); + if (!_atom_indicator_visible_state_on) + { + fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_INDICATOR_ON atom.. %s (%d)\n", __func__, __LINE__); + return 0; + } + } + + if (!_atom_indicator_visible_state_off) + { + _atom_indicator_visible_state_off = XInternAtom (dpy, "_E_ILLUME_INDICATOR_OFF", False); + if (!_atom_indicator_visible_state_off) + { + fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_INDICATOR_OFF atom.. %s (%d)\n", __func__, __LINE__); + return 0; + } + } + + return 1; +} + +API void utilx_enable_indicator (Display* dpy, Window win, int enable) +{ + UTILX_TRACE ("[UTILX] utilx_indicator_set_visible_state... win = %x, show_state = %d\n", win, enable); + + if (dpy == NULL) + { + fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__); + return; + } + + if (!_utilx_get_indicator_atoms(dpy)) + { + fprintf (stderr, "[UTILX] Error.. Cannot create atoms.. %s (%d)\n", __func__, __LINE__); + return; + } + + if (enable == 1) + { + _utilx_set_window_property (dpy, win, _atom_indicator_visible_state, XA_ATOM, + (unsigned int *)&_atom_indicator_visible_state_on, 1); + } + else + { + _utilx_set_window_property (dpy, win, _atom_indicator_visible_state, XA_ATOM, + (unsigned int *)&_atom_indicator_visible_state_off, 1); + } +} + + +API int utilx_get_indicator_state (Display* dpy, Window win) +{ + UTILX_TRACE ("[UTILX] utilx_indicator_set_visible_state... win = %x, show_state = %d\n", win, enable); + + int ret; + Atom state; + + if (dpy == NULL) + { + fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__); + return -1; + } + + if (!_utilx_get_indicator_atoms(dpy)) + { + fprintf (stderr, "[UTILX] Error.. Cannot create atoms.. %s (%d)\n", __func__, __LINE__); + return -1; + } + + ret = _utilx_get_window_property (dpy, win, _atom_indicator_visible_state, XA_ATOM, + (unsigned int *)&state, 1); + + if (ret > 0) + { + if (state == _atom_indicator_visible_state_on) + return 1; + else if (state == _atom_indicator_visible_state_off) + return 0; + else + return -1; + } + else + return -1; +} + +static void +_utilx_set_window_property (Display* dpy, Window win, Atom atom, Atom type, unsigned int *val, unsigned int num) +{ + XChangeProperty (dpy, win, atom, type, 32, PropModeReplace, (unsigned char *)val, num); + XSync(dpy, 0 ); +} + + +static int +_utilx_get_window_property (Display* dpy, Window win, Atom atom, Atom type, unsigned int *val, unsigned int len) +{ + unsigned char* prop_ret; + Atom type_ret; + unsigned long bytes_after, num_ret; + int format_ret; + unsigned int i; + int num; + + prop_ret = NULL; + if (XGetWindowProperty(dpy, win, atom, 0, 0x7fffffff, False, + type, &type_ret, &format_ret, &num_ret, + &bytes_after, &prop_ret) != Success) + { + return -1; + } + + if (type_ret != type || format_ret != 32) + { + num = -1; + } + else if (num_ret == 0 || !prop_ret) + { + num = 0; + } + else + { + if (num_ret < len) + len = num_ret; + for (i = 0; i < len; i++) + { + val[i] = ((unsigned long *)prop_ret)[i]; + } + num = len; + } + + if (prop_ret) + XFree(prop_ret); + + return num; + +} + + +static unsigned long _get_list_of_grabbed_key (Display *disp, Window win, int **key_list) +{ + Atom ret_type; + int ret_format; + unsigned long nr_item; + unsigned long sz_remains_data; + + if (XGetWindowProperty(disp, win, + _atom_grab_key, 0, 0x7fffffff, False, XA_CARDINAL, + &ret_type, &ret_format, &nr_item, + &sz_remains_data, (unsigned char**)key_list) != Success) + { + nr_item = 0; + } + +// fprintf(stderr, "%d - %lu\n", ret_format, nr_item); + + return nr_item; +} + + +static void _free_list_of_grabbed_key (int *key_list) +{ + if (key_list) { + XFree(key_list); + } +} + + +static void _free_new_list_of_grabbed_key (int *new_key_list) +{ + if (new_key_list) { + free(new_key_list); + } +} + + +static int _search_grabbed_key (int *key_list, int key, unsigned long cnt) +{ + register int i; + + for (i = cnt - 1; i >= 0; i --) { + if (key_list[i] == key) break; + } + + return i; +} + + +static int *_del_grabbed_key (int *key_list, int i, unsigned long *cnt) +{ + int *new_key_list = NULL; + + // Only one element is exists in the list of grabbed key + (*cnt) --; + + if (*cnt == 0) return NULL; + + // Shrink the buffer + new_key_list = malloc((*cnt) * sizeof(int)); + if (new_key_list == NULL) { + perror(__func__); + return NULL; + } + + // copy head + if (i > 0) { + memcpy(new_key_list, key_list, sizeof(int) * i); + } + + // copy tail + if ((*cnt) - i > 0) { + memcpy(new_key_list + i, + key_list + i + 1, + sizeof(int) * ((*cnt) - i) + ); + } + return new_key_list; +} + + +static void _set_exclusive_grab_info_to_root (Display *disp, int keycode, Window win, int grab_mode) +{ + int i; + int *key_list = NULL; + + Atom ret_type; + int ret_format; + unsigned long nr_item; + unsigned long sz_remains_data; + Window ex_grabwin; + + if( grab_mode == EXCLUSIVE_GRAB ) + { + if( _atom_grab_excl_win == None ) + _atom_grab_excl_win = XInternAtom(disp, STR_ATOM_GRAB_EXCL_WIN, False); + ex_grabwin = _atom_grab_excl_win; + } + else if( grab_mode == OR_EXCLUSIVE_GRAB ) + { + if( _atom_grab_or_excl_win == None ) + _atom_grab_or_excl_win = XInternAtom(disp, STR_ATOM_GRAB_OR_EXCL_WIN, False); + ex_grabwin = _atom_grab_or_excl_win; + } + else + return; + + if (XGetWindowProperty(disp, DefaultRootWindow(disp), + ex_grabwin, 0, 0x7fffffff, False, XA_CARDINAL, + &ret_type, &ret_format, &nr_item, + &sz_remains_data, (unsigned char**)&key_list) != Success) + { + fprintf(stderr, "[utilX][%s] Fail to get root window property !\n", __FUNCTION__); + goto out; + } + +#ifdef __DEBUG__ + printf("[%s] keycode = %d\n", __FUNCTION__, keycode); +#endif + + for( i=0 ; i < nr_item ; i++ ) + { + if( key_list && (key_list[i] == keycode) ) + return; + } + + XChangeProperty(disp, DefaultRootWindow(disp), ex_grabwin, XA_CARDINAL, 32, + nr_item ? PropModeAppend : PropModeReplace, (unsigned char *)&keycode, 1); + XSync(disp, False); + +out: + return; +} + + +static void _unset_exclusive_grab_info_to_root (Display *disp, int keycode, int grab_mode) +{ + int i; + unsigned long cnt = 0; + int *key_list = NULL; + int *new_key_list = NULL; + + Atom ret_type; + int ret_format; + unsigned long nr_item; + unsigned long sz_remains_data; + Window ex_grabwin; + + if( grab_mode == EXCLUSIVE_GRAB ) + { + if( _atom_grab_excl_win == None ) + _atom_grab_excl_win = XInternAtom(disp, STR_ATOM_GRAB_EXCL_WIN, False); + ex_grabwin = _atom_grab_excl_win; + } + else if( grab_mode == OR_EXCLUSIVE_GRAB ) + { + if( _atom_grab_or_excl_win == None ) + _atom_grab_or_excl_win = XInternAtom(disp, STR_ATOM_GRAB_OR_EXCL_WIN, False); + ex_grabwin = _atom_grab_or_excl_win; + } + else + return; + + if (XGetWindowProperty(disp, DefaultRootWindow(disp), + ex_grabwin, 0, 0x7fffffff, False, XA_CARDINAL, + &ret_type, &ret_format, &nr_item, + &sz_remains_data, (unsigned char**)&key_list) != Success) + { + nr_item = 0; + } + + if (nr_item == 0) + { + fprintf(stderr, "[utilX][%s] keycode = %d\n", __FUNCTION__, keycode); + goto out; + } + + for( i=0 ; i < nr_item ; i++ ) + { + if( key_list[i] == keycode )//&& grab_mode == EXCLUSIVE_GRAB ) + { + continue; + } + cnt++; + } + +#ifdef __DEBUG__ + fprintf(stderr, "[utilX][%s] cnt = %d, nr_item = %d\n", __FUNCTION__, cnt, nr_item); +#endif + + if( 0 < cnt ) + { + new_key_list = malloc(sizeof(int)*cnt); + cnt = 0; + } + else + new_key_list = NULL; + + if( !new_key_list ) + { + //fprintf(stderr, "[utilX][%s] Fail to allocation memory for new_key_list ! \n", __FUNCTION__); + XDeleteProperty(disp, DefaultRootWindow(disp), ex_grabwin); + XSync(disp, False); + goto out; + } + + for( i=0 ; i < nr_item ; i++ ) + { + if( key_list[i] == keycode )//&& grab_mode == EXCLUSIVE_GRAB ) + { + continue; + } + else + new_key_list[cnt++] = key_list[i]; + } + + if (new_key_list) { + XChangeProperty(disp, DefaultRootWindow(disp), ex_grabwin, XA_CARDINAL, 32, + PropModeReplace, (unsigned char *)new_key_list, cnt); + } + else { + XDeleteProperty(disp, DefaultRootWindow(disp), ex_grabwin); + } + XSync(disp, False); + + if(new_key_list) + free(new_key_list); + +out: + return; +} + + +static int _is_grabbed_key_exclusively (Display* disp, int keycode, int grab_mode) +{ + int i, result = 0; + int *key_list = NULL; + + Atom ret_type; + int ret_format; + unsigned long nr_item; + unsigned long sz_remains_data; + Window ex_grabwin; + + if( grab_mode == EXCLUSIVE_GRAB ) + { + if( _atom_grab_excl_win == None ) + _atom_grab_excl_win = XInternAtom(disp, STR_ATOM_GRAB_EXCL_WIN, False); + ex_grabwin = _atom_grab_excl_win; + } + else if( grab_mode == OR_EXCLUSIVE_GRAB ) + { + if( _atom_grab_or_excl_win == None ) + _atom_grab_or_excl_win = XInternAtom(disp, STR_ATOM_GRAB_OR_EXCL_WIN, False); + ex_grabwin = _atom_grab_or_excl_win; + } + else + return result; + + if (XGetWindowProperty(disp, DefaultRootWindow(disp), + ex_grabwin, 0, 0x7fffffff, False, XA_CARDINAL, + &ret_type, &ret_format, &nr_item, + &sz_remains_data, (unsigned char**)&key_list) != Success) + { + fprintf(stderr, "[%s] Fail to get root window property !\n", __FUNCTION__); + goto out; + } + + for( i=0 ; i < nr_item ; i++ ) + { + if( key_list[i] == keycode ) + return EXCLUSIVE_GRABBED_ALREADY; + } + +out: + return result; +} + +API int utilx_grab_key (Display* disp, Window win, const char* key, int grab_mode) +{ + unsigned long cnt; + int *key_list = NULL; + int i, result = 0; + int keycode = 0; + KeySym keysym; + errno = EINVAL; + + if( NULL == disp ) + { + fprintf(stderr, "[%s] Display is NULL\n", __FUNCTION__); + return -1; + } + + if (_atom_grab_key == None) { + _atom_grab_key = XInternAtom(disp, STR_ATOM_GRAB_KEY, False); + } + + if (!strncmp(key, "Keycode-", 8)) { + keycode = atoi(key + 8); + } else { + keysym = XStringToKeysym(key); + if (keysym == NoSymbol) goto out; + keycode = XKeysymToKeycode(disp, XStringToKeysym(key)); + } + if (keycode == 0) goto out; + + if( grab_mode == EXCLUSIVE_GRAB ) + { + //Window grabWin; + result = _is_grabbed_key_exclusively(disp, keycode, grab_mode); + +#ifdef __DEBUG__ + printf("[%s] _is_grabbed_key_exclusively returns result = %d\n", __FUNCTION__, result); +#endif + + if( result ) + { + fprintf(stderr, "[%s] keycode(%d) was already grabbed exclusively (grab_mode=0x%X) !\n", __FUNCTION__, keycode, grab_mode); + goto out; + } + } + else if( grab_mode == OR_EXCLUSIVE_GRAB ) + { + result = _is_grabbed_key_exclusively(disp, keycode, grab_mode); + + if( result ) + { + fprintf(stderr, "[%s] Keycode(%d) was already grabbed with overridable exclusive mode (grab_mode=0x%x)\n", __FUNCTION__, keycode, grab_mode); + fprintf(stderr, "[%s] Now it will be overridden by a new window(0x%x) !\n", __FUNCTION__, win); + utilx_ungrab_key(disp, win, key); + } + } + + keycode |= grab_mode; + + cnt = _get_list_of_grabbed_key(disp, win, &key_list); + if (cnt > 0) { + i = _search_grabbed_key(key_list, keycode, cnt); + _free_list_of_grabbed_key(key_list); + if ( i != -1 ) { + if( grab_mode == OR_EXCLUSIVE_GRAB ) + { + utilx_ungrab_key(disp, win, key); + } + else + { + fprintf(stderr, "Key is already grabbed\n"); + goto out; + } + } + } + + XChangeProperty(disp, win, _atom_grab_key, XA_CARDINAL, 32, + cnt ? PropModeAppend : PropModeReplace, (unsigned char *)&keycode, 1); + XSync(disp, False); + keycode = keycode & (~GRAB_MODE_MASK); +#ifdef __DEBUG__ + printf("[%s] keycode = %d\n", __FUNCTION__, keycode); +#endif + + if( EXCLUSIVE_GRAB == grab_mode || OR_EXCLUSIVE_GRAB == grab_mode ) + _set_exclusive_grab_info_to_root(disp, keycode, win, grab_mode); + + errno = 0; + +out: + + return result; +} + + +API int utilx_ungrab_key (Display* disp, Window win, const char* key) +{ + int i; + unsigned long cnt; + int *key_list = NULL; + int *new_key_list = NULL; + long keycode = 0; + KeySym keysym; + int ret = -1; + errno = EINVAL; + + if( NULL == disp ) + { + fprintf(stderr, "[%s] Display is NULL\n", __FUNCTION__); + return -1; + } + + if (_atom_grab_key == None) { + _atom_grab_key = XInternAtom(disp, STR_ATOM_GRAB_KEY, False); + } + + if (!strncmp(key, "Keycode-", 8)) { + keycode = atoi(key + 8); + } else { + keysym = XStringToKeysym(key); + if (keysym == NoSymbol) goto out; + keycode = XKeysymToKeycode(disp, XStringToKeysym(key)); + } + if (keycode == 0) goto out; + + cnt = _get_list_of_grabbed_key(disp, win, &key_list); + if (cnt == 0) goto out; + + //EXCLUSIVE mode + i = _search_grabbed_key(key_list, keycode | EXCLUSIVE_GRAB, cnt); + + if ( i == -1) + { + //OR_EXCLUSIVE mode + i = _search_grabbed_key(key_list, keycode | OR_EXCLUSIVE_GRAB, cnt); + + if ( i == -1) + { + //TOP_POSITION mode + i = _search_grabbed_key(key_list, keycode | TOP_POSITION_GRAB, cnt); + + if (i == -1) + { + //SHARED mode + i = _search_grabbed_key(key_list, keycode | SHARED_GRAB, cnt); + + if (i == -1) + { + _free_list_of_grabbed_key(key_list); + goto out; + } + } + } + else + { + _unset_exclusive_grab_info_to_root(disp, keycode, OR_EXCLUSIVE_GRAB); + } + } + else + { + _unset_exclusive_grab_info_to_root(disp, keycode, EXCLUSIVE_GRAB); + } + + new_key_list = _del_grabbed_key(key_list, i, &cnt); + _free_list_of_grabbed_key(key_list); + + if (new_key_list) { + XChangeProperty(disp, win, _atom_grab_key, XA_CARDINAL, 32, + PropModeReplace, (unsigned char *)new_key_list, cnt); + } + else { + XDeleteProperty(disp, win, _atom_grab_key); + } + XSync(disp, False); + + _free_new_list_of_grabbed_key(new_key_list); + ret = 0; + errno = 0; + +out: + + return ret; +} + +API Utilx_Key_Status utilx_get_key_status(Display* dpy, char *key_name) +{ + unsigned char keymap[32]; + static unsigned int masktable[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; + Utilx_Key_Status status = UTILX_KEY_STATUS_UNKNOWN; + + if( !strncmp(key_name, KEY_VOLUMEDOWN, LEN_KEY_VOLUMEDOWN) || + !strncmp(key_name, KEY_VOLUMEUP, LEN_KEY_VOLUMEUP) || + !strncmp(key_name, KEY_PAUSE, LEN_KEY_PAUSE) || + !strncmp(key_name, KEY_SEND, LEN_KEY_SEND) || + !strncmp(key_name, KEY_SELECT, LEN_KEY_VOLUMEDOWN) || + !strncmp(key_name, KEY_END, LEN_KEY_END) || + !strncmp(key_name, KEY_POWER, LEN_KEY_POWER) || + !strncmp(key_name, KEY_CAMERA, LEN_KEY_CAMERA) || + !strncmp(key_name, KEY_CONFIG, LEN_KEY_CONFIG) || + !strncmp(key_name, KEY_PLAYCD, LEN_KEY_PLAYCD) || + !strncmp(key_name, KEY_STOPCD, LEN_KEY_STOPCD) || + !strncmp(key_name, KEY_PAUSECD, LEN_KEY_PAUSECD) || + !strncmp(key_name, KEY_NEXTSONG, LEN_KEY_NEXTSONG) || + !strncmp(key_name, KEY_PREVIOUSSONG, LEN_KEY_PREVIOUSSONG) || + !strncmp(key_name, KEY_REWIND, LEN_KEY_REWIND) || + !strncmp(key_name, KEY_FASTFORWARD, LEN_KEY_FASTFORWARD) || + !strncmp(key_name, KEY_MEDIA, LEN_KEY_MEDIA) ) + { + KeySym ks = XStringToKeysym(key_name); + KeyCode kc = XKeysymToKeycode(dpy, ks); + + if( kc ) + { + XQueryKeymap(dpy, (char *)keymap); + if( keymap[kc >> 3] & masktable[kc & 7] ) + status = UTILX_KEY_STATUS_PRESSED; + else + status = UTILX_KEY_STATUS_RELEASED; + } + } + + return status; +} + +API void utilx_set_window_effect_state(Display* dpy, Window win, int state) +{ + if ( dpy == NULL ) + { + fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__); + return; + } + if( !_atom_comp_effect_state) + _atom_comp_effect_state = XInternAtom(dpy, "_NET_CM_WINDOW_EFFECT_ENABLE",False); + + _utilx_set_window_property(dpy, win, _atom_comp_effect_state, XA_CARDINAL, (unsigned int *)&state, 1); + + XSync(dpy, 0 ); +} + +API int utilx_get_window_effect_state(Display* dpy, Window win) +{ + int state = 0; + if( !_atom_comp_effect_state) + _atom_comp_effect_state = XInternAtom(dpy, "_NET_CM_WINDOW_EFFECT_ENABLE",False); + _utilx_get_window_property(dpy, win, _atom_comp_effect_state, XA_CARDINAL, (unsigned int *)&state, 1); + return state; +} + +static void +_utilx_string_set_window_property( Display *dpy, Window win, Atom atom, char *val, unsigned int num) +{ + XChangeProperty( dpy, win, atom, XA_STRING, 8, PropModeReplace, (unsigned char*)val, val ? strlen(val):0 ); +} + +API void utilx_set_fake_launch_img(Display* dpy, Window win, char *file_name) +{ + //UTILX_TRACE ("[UTILX] utilx_set_effect_state... win = %x, show_state = %d\n", win, enable); + + if ( dpy == NULL ) + { + fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__); + return; + } + if( !_atom_comp_fake_launch_image) + _atom_comp_fake_launch_image = XInternAtom(dpy, "_E_COMP_FAKE_LAUNCH_IMAGE",False); + + _utilx_string_set_window_property(dpy, win, _atom_comp_fake_launch_image, file_name, 1); +} + +API void utilx_show_fake_effect( Display *dpy, Window win, char *fake_image_file ) +{ + XEvent xev; + + _atom_comp_fake_launch = XInternAtom( dpy, "_E_COMP_FAKE_LAUNCH", False ); + + if( !_atom_comp_fake_launch ) + { + fprintf( stderr, "XInternAtom(_E_COMP_FAKE_LAUNCH) failed.\n" ); + return; + } + + utilx_set_fake_launch_img(dpy, win, fake_image_file); + + XSync(dpy, 0 ); + + // send fake client message + xev.xclient.type = ClientMessage; + xev.xclient.display = dpy; + xev.xclient.window = win; + xev.xclient.message_type = _atom_comp_fake_launch; + xev.xclient.format = 32; + xev.xclient.data.l[0] = 1; // 1 : start effect , 0 : end effect + xev.xclient.data.l[1] = 0; + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + + XSendEvent( dpy, win, False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev ); + XSync(dpy, 0 ); + +} + + +API void utilx_hide_fake_effect( Display *dpy, Window win) +{ + XEvent xev; + + _atom_comp_fake_launch = XInternAtom( dpy, "_E_COMP_FAKE_LAUNCH", False ); + if( !_atom_comp_fake_launch ) + { + fprintf( stderr, "XInternAtom(_E_COMP_FAKE_LAUNCH) failed.\n" ); + return; + } + + // send fake client message + xev.xclient.type = ClientMessage; + xev.xclient.display = dpy; + xev.xclient.window = win; + xev.xclient.message_type = _atom_comp_fake_launch; + xev.xclient.format = 32; + xev.xclient.data.l[0] = 0; // 1 : start effect , 0 : end effect + xev.xclient.data.l[1] = 0; + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + + XSendEvent( dpy, win, False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev ); + XSync(dpy, 0 ); +} + +static void _utilx_effect_atom_check( Display* dpy ) +{ + if ( dpy == NULL ) + { + fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__); + return; + } + + if( !_atom_comp_window_effect_type) + _atom_comp_window_effect_type = XInternAtom(dpy, "_NET_CM_WINDOW_EFFECT_TYPE",False); + if( !_atom_comp_effect_default ) + _atom_comp_effect_default = XInternAtom(dpy, "_NET_CM_EFFECT_DEFAULT",False); + if( !_atom_comp_effect_none ) + _atom_comp_effect_none = XInternAtom(dpy, "_NET_CM_EFFECT_NONE",False); + if( !_atom_comp_effect_custom0 ) + _atom_comp_effect_custom0 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM0",False); + if( !_atom_comp_effect_custom1 ) + _atom_comp_effect_custom1 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM1",False); + if( !_atom_comp_effect_custom2 ) + _atom_comp_effect_custom2 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM2",False); + if( !_atom_comp_effect_custom3 ) + _atom_comp_effect_custom3 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM3",False); + if( !_atom_comp_effect_custom4 ) + _atom_comp_effect_custom4 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM4",False); + if( !_atom_comp_effect_custom5 ) + _atom_comp_effect_custom5 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM5",False); + if( !_atom_comp_effect_custom6 ) + _atom_comp_effect_custom6 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM6",False); + if( !_atom_comp_effect_custom7 ) + _atom_comp_effect_custom7 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM7",False); + if( !_atom_comp_effect_custom8 ) + _atom_comp_effect_custom8 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM8",False); + if( !_atom_comp_effect_custom9 ) + _atom_comp_effect_custom9 = XInternAtom(dpy, "_NET_CM_EFFECT_CUSTOM9",False); +} + +static Atom _utilx_convert_style_to_atom( Display* dpy, Utilx_Effect_Style style ) +{ + if ( dpy == NULL ) + { + fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__); + return _atom_comp_effect_none; + } + _utilx_effect_atom_check(dpy); + + if ( style == UTILX_EFFECT_STYLE_DEFAULT ) return _atom_comp_effect_default; + else if ( style == UTILX_EFFECT_STYLE_NONE ) return _atom_comp_effect_none; + else if ( style == UTILX_EFFECT_STYLE_CUSTOM0 ) return _atom_comp_effect_custom0; + else if ( style == UTILX_EFFECT_STYLE_CUSTOM1 ) return _atom_comp_effect_custom1; + else if ( style == UTILX_EFFECT_STYLE_CUSTOM2 ) return _atom_comp_effect_custom2; + else if ( style == UTILX_EFFECT_STYLE_CUSTOM3 ) return _atom_comp_effect_custom3; + else if ( style == UTILX_EFFECT_STYLE_CUSTOM4 ) return _atom_comp_effect_custom4; + else if ( style == UTILX_EFFECT_STYLE_CUSTOM5 ) return _atom_comp_effect_custom5; + else if ( style == UTILX_EFFECT_STYLE_CUSTOM6 ) return _atom_comp_effect_custom6; + else if ( style == UTILX_EFFECT_STYLE_CUSTOM7 ) return _atom_comp_effect_custom7; + else if ( style == UTILX_EFFECT_STYLE_CUSTOM8 ) return _atom_comp_effect_custom8; + else if ( style == UTILX_EFFECT_STYLE_CUSTOM9 ) return _atom_comp_effect_custom9; + else return _atom_comp_effect_none; + +} + +static Utilx_Effect_Style _utilx_convert_atom_to_style( Display* dpy, Atom style ) +{ + if ( dpy == NULL ) + { + fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__); + return UTILX_EFFECT_STYLE_NONE; + } + _utilx_effect_atom_check(dpy); + + if ( style == _atom_comp_effect_default ) return UTILX_EFFECT_STYLE_DEFAULT; + else if ( style == _atom_comp_effect_none ) return UTILX_EFFECT_STYLE_NONE; + else if ( style == _atom_comp_effect_custom0 ) return UTILX_EFFECT_STYLE_CUSTOM0; + else if ( style == _atom_comp_effect_custom1 ) return UTILX_EFFECT_STYLE_CUSTOM1; + else if ( style == _atom_comp_effect_custom2 ) return UTILX_EFFECT_STYLE_CUSTOM2; + else if ( style == _atom_comp_effect_custom3 ) return UTILX_EFFECT_STYLE_CUSTOM3; + else if ( style == _atom_comp_effect_custom4 ) return UTILX_EFFECT_STYLE_CUSTOM4; + else if ( style == _atom_comp_effect_custom5 ) return UTILX_EFFECT_STYLE_CUSTOM5; + else if ( style == _atom_comp_effect_custom6 ) return UTILX_EFFECT_STYLE_CUSTOM6; + else if ( style == _atom_comp_effect_custom7 ) return UTILX_EFFECT_STYLE_CUSTOM7; + else if ( style == _atom_comp_effect_custom8 ) return UTILX_EFFECT_STYLE_CUSTOM8; + else if ( style == _atom_comp_effect_custom9 ) return UTILX_EFFECT_STYLE_CUSTOM9; + else return UTILX_EFFECT_STYLE_DEFAULT; +} + +API void utilx_set_window_effect_style(Display* dpy, Window win, Utilx_Effect_Type type, Utilx_Effect_Style style) +{ + Atom *window_effect_type_list = NULL; + if ( dpy == NULL ) + { + fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__); + return; + } + _utilx_effect_atom_check(dpy); + + window_effect_type_list = (Atom *)malloc(sizeof(Atom) * 6); + + if ( !window_effect_type_list ) + { + fprintf (stderr, "[UTILX] Error.. malloc().. %s (%d)\n", __func__, __LINE__); + return; + } + + window_effect_type_list[0] = _atom_comp_effect_default; + window_effect_type_list[1] = _atom_comp_effect_default; + window_effect_type_list[2] = _atom_comp_effect_default; + window_effect_type_list[3] = _atom_comp_effect_default; + window_effect_type_list[4] = _atom_comp_effect_default; + window_effect_type_list[5] = _atom_comp_effect_default; + + _utilx_get_window_property(dpy, win, _atom_comp_window_effect_type, XA_ATOM, (unsigned int *)window_effect_type_list, 6); + + if ( type == UTILX_EFFECT_TYPE_MAP ) window_effect_type_list[0] = _utilx_convert_style_to_atom(dpy, style); + else if ( type == UTILX_EFFECT_TYPE_UNMAP ) window_effect_type_list[1] = _utilx_convert_style_to_atom(dpy, style); + else if ( type == UTILX_EFFECT_TYPE_RAISEABOVE ) window_effect_type_list[2] = _utilx_convert_style_to_atom(dpy, style); + else if ( type == UTILX_EFFECT_TYPE_ROTATION ) window_effect_type_list[3] = _utilx_convert_style_to_atom(dpy, style); + else if ( type == UTILX_EFFECT_TYPE_FOCUSIN ) window_effect_type_list[4] = _utilx_convert_style_to_atom(dpy, style); + else if ( type == UTILX_EFFECT_TYPE_FOCUSOUT ) window_effect_type_list[5] = _utilx_convert_style_to_atom(dpy, style); + + _utilx_set_window_property(dpy, win, _atom_comp_window_effect_type, XA_ATOM, (unsigned int *)window_effect_type_list, 6); + + XSync(dpy, 0 ); + free(window_effect_type_list); +} + +API Utilx_Effect_Style utilx_get_window_effect_style(Display* dpy, Window win, Utilx_Effect_Type type) +{ + Atom *window_effect_type_list = NULL; + Utilx_Effect_Style style = UTILX_EFFECT_STYLE_DEFAULT; + + if ( dpy == NULL ) + { + fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__); + return UTILX_EFFECT_STYLE_NONE; + } + _utilx_effect_atom_check(dpy); + + window_effect_type_list = (Atom *)malloc(sizeof(Atom) * 6); + + if ( !window_effect_type_list ) + { + fprintf (stderr, "[UTILX] Error.. malloc().. %s (%d)\n", __func__, __LINE__); + return UTILX_EFFECT_STYLE_NONE; + } + + if ( _utilx_get_window_property(dpy, win, _atom_comp_window_effect_type, XA_ATOM, (unsigned int *)window_effect_type_list, 6) != 6 ) + { + fprintf (stderr, "[UTILX] Error.. get property failed!.. %s (%d)\n", __func__, __LINE__); + free(window_effect_type_list); + return UTILX_EFFECT_STYLE_NONE; + } + + if ( type == UTILX_EFFECT_TYPE_MAP ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[0]); + else if ( type == UTILX_EFFECT_TYPE_UNMAP ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[1]); + else if ( type == UTILX_EFFECT_TYPE_RAISEABOVE ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[2]); + else if ( type == UTILX_EFFECT_TYPE_ROTATION ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[3]); + else if ( type == UTILX_EFFECT_TYPE_FOCUSIN ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[4]); + else if ( type == UTILX_EFFECT_TYPE_FOCUSOUT ) style = _utilx_convert_atom_to_style(dpy, window_effect_type_list[5]); + + XSync(dpy, 0 ); + free(window_effect_type_list); + return style; +} + +API int utilx_set_window_opaque_state (Display* dpy, Window win, Utilx_Opaque_State state) +{ + UTILX_TRACE ("[UTILX] utilx_set_window_opaque_state... win = %x, show_state = %d\n", win, state); + + unsigned int is_opaque; + + if (dpy == NULL) + { + fprintf (stderr, "[UTILX] Error.. Invald Display.. %s (%d)\n", __func__, __LINE__); + return 0; + } + + switch (state) + { + case UTILX_OPAQUE_STATE_OFF: + is_opaque = 0; + break; + + case UTILX_OPAQUE_STATE_ON: + is_opaque = 1; + break; + + default: + fprintf (stderr, "[UTILX] Error.. Invald State.. %s (%d)\n", __func__, __LINE__); + return 0; + } + + if (!_atom_window_opaque) + { + _atom_window_opaque = XInternAtom (dpy, "_E_ILLUME_WINDOW_REGION_OPAQUE", False); + if (!_atom_window_opaque) + { + fprintf (stderr, "[UTILX] Error.. Cannot create _E_ILLUME_WINDOW_REGION_OPAQUE atom.. %s (%d)\n", __func__, __LINE__); + return 0; + } + } + + _utilx_set_window_property (dpy, win, _atom_window_opaque, XA_CARDINAL, + (unsigned int *)&is_opaque, 1); + + return 1; +} + +static void +_utilx_screen_capture_atom_ensure (Display* dpy) +{ + if (_atom_screen_capture_disable) + return; + + _atom_screen_capture_disable = XInternAtom (dpy, "_CB_SCREEN_CAPTURE_DISABLE", False); + if (_atom_screen_capture_disable) + return; + + fprintf (stderr, "[UTILX] Error.. Cannot create _CB_SCREEN_CAPTURE_DISABLE atom.. %s (%d)\n", __func__, __LINE__); +} + +API int +utilx_set_screen_capture(Display* dpy, int enable) +{ + Window root; + int disable; + + if (!dpy) + { + fprintf (stderr, "[UTILX] Error.. dpy is NULL %s (%d)\n", __func__, __LINE__); + return 0; + } + + root = RootWindow (dpy, DefaultScreen(dpy)); + disable = (enable) ? 0 : 1; + + _utilx_screen_capture_atom_ensure (dpy); + + _utilx_set_window_property (dpy, root, _atom_screen_capture_disable, XA_CARDINAL, (unsigned int *)&disable, 1); + + return 1; +} + +API int +utilx_get_screen_capture(Display* dpy) +{ + Window root; + int disable = 0; + + if (!dpy) + { + fprintf (stderr, "[UTILX] Error.. dpy is NULL %s (%d)\n", __func__, __LINE__); + return 0; + } + + root = RootWindow (dpy, DefaultScreen(dpy)); + + _utilx_screen_capture_atom_ensure (dpy); + + _utilx_get_window_property(dpy, root, _atom_screen_capture_disable, XA_CARDINAL, + (unsigned int *)&disable, 1); + + return (disable) ? 0 : 1; +} + +API void utilx_set_window_cardinal_property(Display* dpy, Window win, Atom atom, unsigned int *value) +{ + _utilx_set_window_property(dpy, win, atom, XA_CARDINAL, value, 1); +} + +API int utilx_get_window_cardinal_property (Display* dpy, Window win, Atom atom, unsigned int *value) +{ + return _utilx_get_window_property(dpy, win, atom, XA_CARDINAL, value, 1); +} + +API void utilx_show_capture_effect( Display *dpy, Window win) +{ + XEvent xev; + + _atom_comp_capture_effect = XInternAtom( dpy, "_E_COMP_CAPTURE_EFFECT", False ); + if( !_atom_comp_capture_effect ) + { + fprintf( stderr, "XInternAtom(_E_COMP_CAPTURE_EFFECT) failed.\n" ); + return; + } + + // send capture effect client message + xev.xclient.type = ClientMessage; + xev.xclient.display = dpy; + xev.xclient.window = win; + xev.xclient.message_type = _atom_comp_capture_effect; + xev.xclient.format = 32; + xev.xclient.data.l[0] = 0; + xev.xclient.data.l[1] = 0; + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + + XSendEvent( dpy, win, False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev ); + XSync(dpy, 0 ); +} + +API UtilxScrnConf *utilx_scrnconf_allocate (void) +{ + UtilxScrnConf *scrnconf = calloc (1, sizeof(UtilxScrnConf)); + if (!scrnconf) + { + fprintf (stderr, "fail to allocate UtilxScrnConf\n"); + return NULL; + } + + return scrnconf; +} + +API void utilx_scrnconf_free (UtilxScrnConf *scrnconf) +{ + if (!scrnconf) + return; + + if (scrnconf->str_output) + free (scrnconf->str_output); + + if (scrnconf->str_resolution) + free (scrnconf->str_resolution); + + free(scrnconf); + scrnconf = NULL; +} + +API int utilx_scrnconf_get_info (Display *dpy, UtilxScrnConf *scrnconf) +{ + Window win = DefaultRootWindow(dpy); + Atom scrnconf_atom = None; + XTextProperty xtp; + char *str = NULL; + char *ptr = NULL; + int items; + char **list = NULL; + int i = 0; + int s; + + scrnconf_atom = XInternAtom (dpy, "_SCRNCONF_INFO", False); + + /* get property */ + if (XGetTextProperty (dpy, win, &xtp, scrnconf_atom)) + { + s = XmbTextPropertyToTextList (dpy, &xtp, &list, &items); + if ((s == XLocaleNotSupported) || + (s == XNoMemory) || (s == XConverterNotFound)) + str = strdup((char *)xtp.value); + else if ((s >= Success) && (items > 0)) + str = strdup(list[0]); + + if (list) + XFreeStringList (list); + + XFree(xtp.value); + } + + ptr = strtok (str, ","); + while (ptr != NULL) + { + if (i == 0) + { + scrnconf->str_output = calloc (1, strlen(ptr)); + if (!scrnconf->str_output) + goto fail; + + strcpy (scrnconf->str_output, ptr); + } + else if (i == 1) + { + if (!strcmp(ptr, "CONNECT")) + scrnconf->status = UTILX_SCRNCONF_STATUS_CONNECT; + else if (!strcmp(ptr, "ACTIVE")) + scrnconf->status = UTILX_SCRNCONF_STATUS_ACTIVE; + else + scrnconf->status = UTILX_SCRNCONF_STATUS_NULL; + } + else if (i == 2) + { + scrnconf->str_resolution = calloc (1, strlen(ptr)); + if (!scrnconf->str_resolution) + goto fail; + + strcpy (scrnconf->str_resolution, ptr); + } + else if (i == 3) + { + if (!strcmp(ptr, "CLONE")) + scrnconf->dispmode = UTILX_SCRNCONF_DISPMODE_CLONE; + else if (!strcmp(ptr, "EXTENDED")) + scrnconf->dispmode = UTILX_SCRNCONF_DISPMODE_EXTENDED; + else + scrnconf->dispmode = UTILX_SCRNCONF_DISPMODE_NULL; + } + else + break; + + ptr = strtok (NULL, ","); + i++; + } + + free (str); + + return 1; +fail: + if (str) + free (str); + + return 0; +} + +API int utilx_scrnconf_set_dispmode (Display *dpy, Utilx_Scrnconf_Dispmode dispmode) +{ + Window win = DefaultRootWindow(dpy); + XEvent xev; + Atom scrnconf_atom = None; + UtilxScrnConf *scrnconf = NULL; + + scrnconf = utilx_scrnconf_allocate (); + if (!scrnconf) + return 0; + + if (!utilx_scrnconf_get_info (dpy, scrnconf)) + { + utilx_scrnconf_free (scrnconf); + return 0; + } + + if (scrnconf->status == UTILX_SCRNCONF_STATUS_NULL) + { + fprintf (stderr, "[utilx_scrnconf]: the status of screen configuration is null\n"); + utilx_scrnconf_free (scrnconf); + return 0; + } + + if (scrnconf->dispmode == dispmode) + { + fprintf (stderr, "[utilx_scrnconf]: dispmode (%d) already set\n", dispmode); + utilx_scrnconf_free (scrnconf); + return 1; + } + + utilx_scrnconf_free (scrnconf); + + scrnconf_atom = XInternAtom (dpy, "_SCRNCONF_DISPMODE_SET", False); + + xev.xclient.window = win; + xev.xclient.type = ClientMessage; + xev.xclient.message_type = scrnconf_atom; + xev.xclient.format = 32; + xev.xclient.data.s[0] = dispmode; + + XSendEvent(dpy, win, False, StructureNotifyMask, &xev); + XSync(dpy, False); + + return 1; +} + +typedef struct _ShotInfo +{ + Display *dpy; + + /* GetStill */ + int port; + unsigned int width; + unsigned int height; + Pixmap pixmap; + GC gc; + + /* Damage */ + Damage damage; + int damage_base; + + /* Dri2 */ + int drm_fd; + drm_slp_bufmgr bufmgr; + void *virtual; + DRI2Buffer* dri2_buffers; + drm_slp_bo bo; + + /* XShm */ + Bool enable_xshm; + XImage *image; + XShmSegmentInfo shminfo; +} ShotInfo; + +#define FOURCC(a,b,c,d) (((unsigned)d&0xff)<<24 | ((unsigned)c&0xff)<<16 | ((unsigned)b&0xff)<<8 | ((unsigned)a&0xff)) + +#define FOURCC_RGB32 FOURCC('R','G','B','4') + + /* x error handling */ +static Bool x_error_caught; + +static ShotInfo *shot_info; + +static int +_get_port (Display *dpy, unsigned int id) +{ + unsigned int ver, rev, req_base, evt_base, err_base; + unsigned int adaptors; + XvAdaptorInfo *ai = NULL; + XvImageFormatValues *fo = NULL; + int formats; + int i, j, p; + + if (XvQueryExtension (dpy, &ver, &rev, &req_base, &evt_base, &err_base) != Success) + { + fprintf (stderr, "[UTILX] no XV extension. \n"); + return -1; + } + + if (XvQueryAdaptors (dpy, DefaultRootWindow (dpy), &adaptors, &ai) != Success) + { + fprintf (stderr, "[UTILX] fail : query adaptors. \n"); + return -1; + } + + if (!ai) + { + fprintf (stderr, "[UTILX] fail : get adaptor info. \n"); + return -1; + } + + for (i = 0; i < adaptors; i++) + { + int support_format = False; + + if (!(ai[i].type & XvStillMask)) + continue; + + p = ai[i].base_id; + + fo = XvListImageFormats (dpy, p, &formats); + for (j = 0; j < formats; j++) + if (fo[j].id == (int)id) + support_format = True; + + if (fo) + XFree (fo); + + if (!support_format) + continue; + + if (XvGrabPort (dpy, p, 0) == Success) + { + XvFreeAdaptorInfo (ai); + return p; + } + + fprintf (stderr, "[UTILX] fail : grab port. \n"); + } + + XvFreeAdaptorInfo (ai); + + return -1; +} + +static void +_deinit_screen_shot (ShotInfo *info) +{ + static Atom atom_stream_off = None; + + if (!info) + return; + + if (atom_stream_off == None) + atom_stream_off = XInternAtom (info->dpy, "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF", False); + + XvSetPortAttribute (info->dpy, info->port, atom_stream_off, 1); + + if (info->image) + XDestroyImage (info->image); + if (info->shminfo.shmid != -1) + { + XShmDetach (info->dpy, &info->shminfo); + shmdt (info->shminfo.shmaddr); + shmctl (info->shminfo.shmid, IPC_RMID, 0); + } + + if (info->bo) + drm_slp_bo_unref(info->bo); + if (info->dri2_buffers) + free(info->dri2_buffers); + if (info->bufmgr) + drm_slp_bufmgr_destroy (info->bufmgr); + if (info->drm_fd >= 0) + close (info->drm_fd); + + if (info->damage) + XDamageDestroy (info->dpy, info->damage); + + if (info->gc) + XFreeGC (info->dpy, info->gc); + if (info->pixmap > 0) + XFreePixmap (info->dpy, info->pixmap); + if (info->port > 0) + XvUngrabPort (info->dpy, info->port, 0); + + free (info); + shot_info = NULL; +} + +static int +_screen_shot_x_error_handle (Display *dpy, XErrorEvent *ev) +{ + char error_msg[1024]; + + if (!shot_info || (dpy != shot_info->dpy)) + return 0; + + XGetErrorText (dpy, ev->error_code, error_msg, 1024); + fprintf (stderr, "[UTILX] get XError: %s\n", error_msg); + + x_error_caught = True; + + return 0; +} + +static Bool +_init_screen_shot_damage (ShotInfo *info) +{ + int damage_err_base = 0; + + if (!XDamageQueryExtension(info->dpy, &info->damage_base, &damage_err_base)) + { + fprintf (stderr, "[UTILX] no X Damage extension. \n"); + return False; + } + + info->damage = XDamageCreate (info->dpy, info->pixmap, XDamageReportNonEmpty); + if (info->damage <= 0) + { + fprintf (stderr, "[UTILX] fail : create damage \n"); + return False; + } + + return True; +} + +static Bool +_init_screen_shot_dri2 (ShotInfo *info) +{ + int screen; + int dri2_base = 0; + int dri2_err_base = 0; + int dri2Major, dri2Minor; + char *driverName = NULL, *deviceName = NULL; + unsigned int attachments[1]; + int dri2_count, dri2_out_count; + int dri2_width, dri2_height, dri2_stride; + drm_magic_t magic; + + screen = DefaultScreen(info->dpy); + if (!DRI2QueryExtension (info->dpy, &dri2_base, &dri2_err_base)) + { + fprintf (stderr, "[UTILX] no DRI2 extension. !!\n"); + goto fail_init_dri2; + } + + if (!DRI2QueryVersion (info->dpy, &dri2Major, &dri2Minor)) + { + fprintf (stderr, "[UTILX] fail : DRI2QueryVersion !!\n"); + goto fail_init_dri2; + } + + if (!DRI2Connect (info->dpy, RootWindow(info->dpy, screen), &driverName, &deviceName)) + { + fprintf (stderr, "[UTILX] fail : DRI2Connect !!\n"); + goto fail_init_dri2; + } + + /* drm_fd */ + info->drm_fd = open (deviceName, O_RDWR); + if (info->drm_fd < 0) + { + fprintf (stderr, "[UTILX] fail : open drm device (%s)\n", deviceName); + goto fail_init_dri2; + } + + /* get the drm magic */ + drmGetMagic(info->drm_fd, &magic); + if (!DRI2Authenticate(info->dpy, RootWindow(info->dpy, screen), magic)) + { + fprintf (stderr, "[UTILX] fail : DRI2Authenticate (%d)\n", magic); + goto fail_init_dri2; + } + + /* bufmgr */ + info->bufmgr = drm_slp_bufmgr_init (info->drm_fd, NULL); + if (!info->bufmgr) + { + fprintf (stderr, "[UTILX] fail : init buffer manager \n"); + goto fail_init_dri2; + } + + DRI2CreateDrawable (info->dpy, info->pixmap); + + attachments[0] = DRI2BufferFrontLeft; + dri2_count = 1; + info->dri2_buffers = DRI2GetBuffers (info->dpy, info->pixmap, &dri2_width, &dri2_height, + attachments, dri2_count, &dri2_out_count); + + if (!info->dri2_buffers) + { + fprintf (stderr, "[UTILX] fail : get buffers\n"); + goto fail_init_dri2; + } + + if (!info->dri2_buffers[0].name) + { + fprintf (stderr, "[UTILX] fail : a handle of the dri2 buffer is null \n "); + goto fail_init_dri2; + } + + info->bo = drm_slp_bo_import (info->bufmgr, info->dri2_buffers[0].name); + if (!info->bo) + { + fprintf (stderr, "[UTILX] fail : import bo (key:%d)\n", info->dri2_buffers[0].name); + goto fail_init_dri2; + } + + dri2_stride = info->dri2_buffers[0].pitch; + + /* virtual */ + info->virtual = (void*)drm_slp_bo_get_handle (info->bo, DRM_SLP_DEVICE_CPU); + if (!info->virtual) + { + fprintf (stderr, "[UTILX] fail : map \n"); + goto fail_init_dri2; + } + + info->enable_xshm = False; + + return True; + +fail_init_dri2: + + if (info->bo) + drm_slp_bo_unref(info->bo); + if (info->dri2_buffers) + free(info->dri2_buffers); + if (info->bufmgr) + drm_slp_bufmgr_destroy (info->bufmgr); + if (info->drm_fd >= 0) + close (info->drm_fd); + + return False; +} + +static Bool +_init_screen_shot_shm (ShotInfo *info) +{ + if (!XShmQueryExtension (info->dpy)) + { + fprintf (stderr, "[UTILX] no XShm extension. !!\n"); + return False; + } + + info->image = XShmCreateImage (info->dpy, + DefaultVisual (info->dpy, DefaultScreen (info->dpy)), + DefaultDepth (info->dpy, DefaultScreen (info->dpy)), + ZPixmap, + NULL, + &info->shminfo, + info->width, + info->height); + if (!info->image) + { + fprintf (stderr, "[UTILX] fail : XShmCreateImage \n"); + return False; + } + + info->shminfo.shmid = shmget (IPC_PRIVATE, info->image->bytes_per_line * info->height, IPC_CREAT | 0777); + if (info->shminfo.shmid == -1) + { + XDestroyImage (info->image); + fprintf (stderr, "[UTILX] fail : shmget\n"); + return False; + } + + info->shminfo.shmaddr = shmat (info->shminfo.shmid, 0, 0); + if (info->shminfo.shmaddr == (void *) -1) + { + XDestroyImage (info->image); + shmctl (info->shminfo.shmid, IPC_RMID, 0); + info->shminfo.shmid = -1; + fprintf (stderr, "[UTILX] fail : shmat\n"); + return False; + } + + info->shminfo.readOnly = False; + + if (!XShmAttach (info->dpy, &info->shminfo)) + { + XDestroyImage (info->image); + shmdt (info->shminfo.shmaddr); + shmctl (info->shminfo.shmid, IPC_RMID, 0); + info->shminfo.shmid = -1; + fprintf (stderr, "[UTILX] fail : XShmAttach\n"); + return False; + } + + info->image->data = info->shminfo.shmaddr; + info->virtual = info->shminfo.shmaddr; + + info->enable_xshm = True; + + return True; +} + +static ShotInfo* +_init_screen_shot (Display* dpy, unsigned int width, unsigned int height) +{ + ShotInfo *info = NULL; + static Atom atom_capture = None; + + if (shot_info) + { + if (shot_info->width == width && shot_info->height == height) + return shot_info; + + _deinit_screen_shot (shot_info); + } + + info = calloc (1, sizeof (ShotInfo)); + if (!info) + goto fail_init; + + shot_info = info; + + /* dpy */ + info->dpy = dpy; + info->shminfo.shmid = -1; + info->shminfo.shmaddr = (void*)-1; + info->drm_fd = -1; + + /* port */ + info->port = _get_port (info->dpy, FOURCC_RGB32); + if (info->port <= 0) + goto fail_init; + + /* width, height */ + if (atom_capture == None) + atom_capture = XInternAtom (info->dpy, "_USER_WM_PORT_ATTRIBUTE_CAPTURE", False); + + XvSetPortAttribute (info->dpy, info->port, atom_capture, 1); + XvQueryBestSize (info->dpy, info->port, 0, 0, 0, width, height, &width, &height); + if (width <= 0 || height <= 0) + goto fail_init; + info->width = width; + info->height = height; + + /* pixmap */ + info->pixmap = XCreatePixmap (info->dpy, + DefaultRootWindow (info->dpy), + width, height, + DefaultDepth (info->dpy, DefaultScreen (info->dpy))); + if (info->pixmap <= 0) + { + fprintf (stderr, "[UTILX] fail : create pixmap. \n"); + goto fail_init; + } + + /* gc */ + info->gc = XCreateGC (info->dpy, info->pixmap, 0, 0); + if (info->gc <= 0) + { + fprintf (stderr, "[UTILX] fail : create gc. \n"); + goto fail_init; + } + + XSetForeground (info->dpy, info->gc, 0xFF000000); + XFillRectangle (info->dpy, info->pixmap, info->gc, 0, 0, width, height); + + if (!_init_screen_shot_damage (info)) + goto fail_init; + + if (!_init_screen_shot_dri2 (info)) + { + if (!_init_screen_shot_shm (info)) + goto fail_init; + else + fprintf (stderr, "[UTILX] XShm success. !!\n"); + } + + if (!info->virtual) + { + fprintf (stderr, "[UTILX] fail : get virtual \n"); + goto fail_init; + } + + XFlush (info->dpy); + + return info; + +fail_init: + _deinit_screen_shot (info); + return NULL; +} + +API void* +utilx_create_screen_shot (Display* dpy, int width, int height) +{ + ShotInfo *info; + XEvent ev; + XErrorHandler old_handler = NULL; + + if (dpy <= 0) + { + fprintf (stderr, "[UTILX] invalid display(%p) \n", dpy); + return NULL; + } + + if (width <= 0 || height <= 0) + { + fprintf (stderr, "[UTILX] invalid size(%dx%d) \n", width, height); + return NULL; + } + + XSync (dpy, 0); + + x_error_caught = False; + old_handler = XSetErrorHandler (_screen_shot_x_error_handle); + + info = _init_screen_shot (dpy, width, height); + + if (!info) + { + fprintf (stderr, "[UTILX] fail : initialize screenshot. \n"); + return NULL; + } + + XvGetStill (info->dpy, info->port, info->pixmap, info->gc, + 0, 0, info->width, info->height, + 0, 0, info->width, info->height); + + XSync (dpy, 0); + + if (x_error_caught) + { + x_error_caught = False; + XSetErrorHandler (old_handler); + fprintf (stderr, "[UTILX] fail : GetStill. \n"); + return NULL; + } + + x_error_caught = False; + XSetErrorHandler (old_handler); + + XNextEvent (info->dpy, &ev); /* wating for x event */ + + if (ev.type == (info->damage_base + XDamageNotify)) + { + XDamageNotifyEvent *damage_ev = (XDamageNotifyEvent *)&ev; + if (damage_ev->drawable == info->pixmap) + { + if (info->enable_xshm) + XShmGetImage (info->dpy, info->pixmap, info->image, 0, 0, AllPlanes); + + XDamageSubtract (info->dpy, info->damage, None, None ); + return info->virtual; + } + + XDamageSubtract (info->dpy, info->damage, None, None ); + } + + utilx_release_screen_shot (); + + return NULL; +} + +API void +utilx_release_screen_shot (void) +{ + _deinit_screen_shot (shot_info); +} + +#define XRR_PROPERTY_FB_VISIBLE "XRR_PROPERTY_FB_VISIBLE" +#define XRR_PROPERTY_VIDEO_OFFSET "XRR_PROPERTY_VIDEO_OFFSET" + +static Bool +_utilx_xrr_set_property (Display* dpy, Atom atom, unsigned char *buf, int buf_len, unsigned char **get) +{ + Window root = None; + XRRScreenResources *res = NULL; + RROutput rr_output = None; + int i; + + root = XRootWindow (dpy, 0); + if (root == None) + { + fprintf (stderr, "[UTILX] Warning : Root window is None.. %s (%d)\n", __func__, __LINE__); + return False; + } + + res = XRRGetScreenResources (dpy, root); + if (res == NULL || res->noutput == 0) + { + fprintf (stderr, "[UTILX] Warning : ScreenResources is None.. %s (%d)\n", __func__, __LINE__); + return False; + } + + for (i = 0; i < res->noutput; i++) + { + XRROutputInfo *output_info = XRRGetOutputInfo (dpy, res, res->outputs[i]); + if (output_info) + { + if (!strcmp (output_info->name, "LVDS1")) + { + rr_output = res->outputs[i]; + XRRFreeOutputInfo(output_info); + break; + } + XRRFreeOutputInfo(output_info); + } + } + + if (rr_output == None) + { + fprintf (stderr, "[UTILX] Warning : output is None.. %s (%d)\n", __func__, __LINE__); + XRRFreeScreenResources (res); + return False; + } + + XRRChangeOutputProperty (dpy, rr_output, atom, + XA_CARDINAL, 8, PropModeReplace, buf, buf_len); + + if (get) + { + Atom actual_type; + int actual_format; + unsigned long nitems, bytes_after; + + XRRGetOutputProperty (dpy, rr_output, atom, + 0, 1024L, + True, False, XA_CARDINAL, + &actual_type, &actual_format, + &nitems, &bytes_after, + get); + } + + XSync (dpy, 0); + + XRRFreeScreenResources (res); + + return True; +} + +API void +utilx_set_fb_visible (Display* dpy, Utilx_Fb_Type fb, Bool visible) +{ + static Atom property = None; + char buf[8192] = {0,}; + char *p = buf; + int buf_len = 0; + + if (!dpy) + { + fprintf (stderr, "[UTILX] invalid display(%p).. %s (%d)\n", dpy, __func__, __LINE__); + return; + } + + if (fb <= UTILX_FB_TYPE_NONE || fb > UTILX_FB_TYPE_OVERLAY) + { + fprintf (stderr, "[UTILX] Error.. Invald fb(%d).. %s (%d)\n", fb, __func__, __LINE__); + return; + } + + p += sprintf (p, "%d:", 0); + p += sprintf (p, "%d", fb + 2); + p += sprintf (p, ":%d", (visible > 0)? 1 : 0); + + *p = '\0'; + p++; + + buf_len = p - buf; + + if (property == None) + property = XInternAtom (dpy, XRR_PROPERTY_FB_VISIBLE, False); + + if (property == None) + { + fprintf (stderr, "[UTILX] Warning : FB_VISIBLE property is None.. %s (%d)\n", __func__, __LINE__); + return; + } + + if (!_utilx_xrr_set_property (dpy, property, (unsigned char*)buf, buf_len, NULL)) + { + fprintf (stderr, "[UTILX] Warning : set_property failed.. %s (%d)\n", __func__, __LINE__); + return; + } +} + +API Bool +utilx_get_fb_visible (Display* dpy, Utilx_Fb_Type fb) +{ + static Atom property = None; + char buf[32] = {0,}; + char *p = buf; + int buf_len = 0; + unsigned char *prop = NULL; + Bool visible = False; + + if (!dpy) + { + fprintf (stderr, "[UTILX] invalid display(%p).. %s (%d)\n", dpy, __func__, __LINE__); + return False; + } + + if (fb <= UTILX_FB_TYPE_NONE || fb > UTILX_FB_TYPE_OVERLAY) + { + fprintf (stderr, "[UTILX] Error.. Invald fb(%d).. %s (%d)\n", fb, __func__, __LINE__); + return False; + } + + p += sprintf (p, "%d:", 0); + p += sprintf (p, "%d", fb + 2); + + *p = '\0'; + p++; + + buf_len = p - buf; + + if (property == None) + property = XInternAtom (dpy, XRR_PROPERTY_FB_VISIBLE, False); + + if (property == None) + { + fprintf (stderr, "[UTILX] Warning : FB_VISIBLE property is None.. %s (%d)\n", __func__, __LINE__); + return False; + } + + if (!_utilx_xrr_set_property (dpy, property, (unsigned char*)buf, buf_len, &prop)) + { + fprintf (stderr, "[UTILX] Warning : set_property failed.. %s (%d)\n", __func__, __LINE__); + return False; + } + + if (prop) + visible = atoi((char*)prop); + + return visible; +} + +API void +utilx_set_video_offset (Display* dpy, int x, int y) +{ + static Atom property = None; + char buf[32] = {0,}; + char *p = buf; + int buf_len = 0; + + if (!dpy) + { + fprintf (stderr, "[UTILX] invalid display(%p).. %s (%d)\n", dpy, __func__, __LINE__); + return; + } + + p += sprintf (p, "%d,%d", x, y); + + *p = '\0'; + p++; + + buf_len = p - buf; + + if (property == None) + property = XInternAtom (dpy, XRR_PROPERTY_VIDEO_OFFSET, False); + + if (property == None) + { + fprintf (stderr, "[UTILX] Warning : VIDEO_OFFSET property is None.. %s (%d)\n", __func__, __LINE__); + return; + } + + if (!_utilx_xrr_set_property (dpy, property, (unsigned char*)buf, buf_len, NULL)) + { + fprintf (stderr, "[UTILX] Warning : set_property failed.. %s (%d)\n", __func__, __LINE__); + return; + } +} -- 2.7.4