Initial commit
This commit is contained in:
		
							
								
								
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					# Build files
 | 
				
			||||||
 | 
					/build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Qt Creator files
 | 
				
			||||||
 | 
					/CMakeLists.txt.user*
 | 
				
			||||||
 | 
					/wdmtg.config
 | 
				
			||||||
 | 
					/wdmtg.files
 | 
				
			||||||
 | 
					/wdmtg.creator*
 | 
				
			||||||
 | 
					/wdmtg.includes
 | 
				
			||||||
							
								
								
									
										84
									
								
								CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
				
			|||||||
 | 
					project (wdmtg C)
 | 
				
			||||||
 | 
					cmake_minimum_required (VERSION 2.8.12)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Vala really sucks at producing good C code
 | 
				
			||||||
 | 
					if ("${CMAKE_C_COMPILER_ID}" MATCHES "GNU" OR CMAKE_COMPILER_IS_GNUC)
 | 
				
			||||||
 | 
						set (CMAKE_C_FLAGS_RELEASE
 | 
				
			||||||
 | 
							"${CMAKE_C_FLAGS_RELEASE} -Wno-ignored-qualifiers -Wno-incompatible-pointer-types")
 | 
				
			||||||
 | 
					endif ("${CMAKE_C_COMPILER_ID}" MATCHES "GNU" OR CMAKE_COMPILER_IS_GNUC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Options
 | 
				
			||||||
 | 
					option (OPTION_NOINSTALL "Only for developers; work without installing" OFF)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Version
 | 
				
			||||||
 | 
					set (project_VERSION "0.1.0")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Set some variables
 | 
				
			||||||
 | 
					if (OPTION_NOINSTALL)
 | 
				
			||||||
 | 
						set (project_SHARE_DIR ${PROJECT_SOURCE_DIR}/share)
 | 
				
			||||||
 | 
					elseif (WIN32)
 | 
				
			||||||
 | 
						set (project_SHARE_DIR ../share)
 | 
				
			||||||
 | 
						set (project_INSTALL_SHARE_DIR share)
 | 
				
			||||||
 | 
					else (OPTION_NOINSTALL)
 | 
				
			||||||
 | 
						set (project_SHARE_DIR ${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME})
 | 
				
			||||||
 | 
						set (project_INSTALL_SHARE_DIR share/${PROJECT_NAME})
 | 
				
			||||||
 | 
					endif (OPTION_NOINSTALL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Gather package information
 | 
				
			||||||
 | 
					set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
 | 
				
			||||||
 | 
					find_package (Vala 0.12 REQUIRED)
 | 
				
			||||||
 | 
					find_package (PkgConfig REQUIRED)
 | 
				
			||||||
 | 
					pkg_check_modules (dependencies REQUIRED gtk+-3.0 sqlite3 x11 xext xextproto)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Precompile Vala sources
 | 
				
			||||||
 | 
					include (ValaPrecompile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set (HEADER_PATH "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.h")
 | 
				
			||||||
 | 
					set (CONFIG_PATH "${PROJECT_BINARY_DIR}/config.vala")
 | 
				
			||||||
 | 
					configure_file (${PROJECT_SOURCE_DIR}/config.vala.in ${CONFIG_PATH})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# I'm not sure what this was about, look at slovnik-gui for more comments
 | 
				
			||||||
 | 
					set (SYMBOLS_PATH "${PROJECT_BINARY_DIR}/${PROJECT_NAME}.def")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vala_init (${PROJECT_NAME}
 | 
				
			||||||
 | 
						PACKAGES gmodule-2.0 gio-2.0 gtk+-3.0 gee-0.8 sqlite3 x11
 | 
				
			||||||
 | 
						CUSTOM_VAPIS ${PROJECT_SOURCE_DIR}/xsync.vapi)
 | 
				
			||||||
 | 
					vala_add (${PROJECT_NAME} ${CONFIG_PATH})
 | 
				
			||||||
 | 
					vala_add (${PROJECT_NAME} ${PROJECT_NAME}.vala DEPENDS config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vala_finish (${PROJECT_NAME}
 | 
				
			||||||
 | 
						SOURCES project_VALA_SOURCES
 | 
				
			||||||
 | 
						OUTPUTS project_VALA_C
 | 
				
			||||||
 | 
						GENERATE_HEADER ${HEADER_PATH}
 | 
				
			||||||
 | 
						GENERATE_SYMBOLS ${SYMBOLS_PATH})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Include Vala sources as header files, so they appear in the IDE
 | 
				
			||||||
 | 
					# but CMake doesn't try to compile them directly
 | 
				
			||||||
 | 
					set_source_files_properties (${project_VALA_SOURCES}
 | 
				
			||||||
 | 
						PROPERTIES HEADER_FILE_ONLY TRUE)
 | 
				
			||||||
 | 
					set (project_SOURCES ${project_VALA_SOURCES} ${project_VALA_C} ${SYMBOLS_PATH})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Build the executable and install it
 | 
				
			||||||
 | 
					include_directories (${dependencies_INCLUDE_DIRS})
 | 
				
			||||||
 | 
					link_directories (${dependencies_LIBRARY_DIRS})
 | 
				
			||||||
 | 
					add_executable (${PROJECT_NAME} ${project_SOURCES})
 | 
				
			||||||
 | 
					target_link_libraries (${PROJECT_NAME} ${dependencies_LIBRARIES})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install (TARGETS ${PROJECT_NAME} DESTINATION bin)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# CPack
 | 
				
			||||||
 | 
					set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "Activity tracker")
 | 
				
			||||||
 | 
					set (CPACK_PACKAGE_VENDOR "Přemysl Janouch")
 | 
				
			||||||
 | 
					set (CPACK_PACKAGE_CONTACT "Přemysl Janouch <p.janouch@gmail.com>")
 | 
				
			||||||
 | 
					set (CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
 | 
				
			||||||
 | 
					set (CPACK_PACKAGE_VERSION ${project_VERSION})
 | 
				
			||||||
 | 
					set (CPACK_GENERATOR "TGZ;ZIP")
 | 
				
			||||||
 | 
					set (CPACK_PACKAGE_FILE_NAME
 | 
				
			||||||
 | 
						"${PROJECT_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
 | 
				
			||||||
 | 
					set (CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME}-${CPACK_PACKAGE_VERSION}")
 | 
				
			||||||
 | 
					set (CPACK_SOURCE_GENERATOR "TGZ;ZIP")
 | 
				
			||||||
 | 
					set (CPACK_SOURCE_IGNORE_FILES "/build;/\\\\.git")
 | 
				
			||||||
 | 
					set (CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${CPACK_PACKAGE_VERSION}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include (CPack)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										15
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								LICENSE
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					 Copyright (c) 2016, Přemysl Janouch <p.janouch@gmail.com>
 | 
				
			||||||
 | 
					 All rights reserved.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 | 
					 purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					 copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 | 
				
			||||||
 | 
					 SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 | 
				
			||||||
 | 
					 OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 | 
				
			||||||
 | 
					 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										54
									
								
								README.adoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								README.adoc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					wdmtg
 | 
				
			||||||
 | 
					=====
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					'wdmtg' (Where Did My Time Go) is an automatic activity tracker for X11.
 | 
				
			||||||
 | 
					It tracks the current window title and whether the user seems to be idle.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Features
 | 
				
			||||||
 | 
					--------
 | 
				
			||||||
 | 
					Currently it's still under development, stuck in a proof-of-concept phase.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Packages
 | 
				
			||||||
 | 
					--------
 | 
				
			||||||
 | 
					Regular releases are sporadic.  git master should be stable enough.  You can get
 | 
				
			||||||
 | 
					a package with the latest development version from Archlinux's AUR, or from
 | 
				
			||||||
 | 
					openSUSE Build Service for the rest of mainstream distributions.  Consult the
 | 
				
			||||||
 | 
					list of repositories and their respective links at:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					https://build.opensuse.org/project/repositories/home:pjanouch:git
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Building and Running
 | 
				
			||||||
 | 
					--------------------
 | 
				
			||||||
 | 
					Build dependencies: CMake, pkg-config, Vala >= 0.12 +
 | 
				
			||||||
 | 
					Runtime dependencies: gtk+-3.0, sqlite3, x11, xextproto, xext
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 $ git clone --recursive https://github.com/pjanouch/wdmtg.git
 | 
				
			||||||
 | 
					 $ mkdir wdmtg/build
 | 
				
			||||||
 | 
					 $ cd wdmtg/build
 | 
				
			||||||
 | 
					 $ cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug
 | 
				
			||||||
 | 
					 $ make
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To install the application, you can do either the usual:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 # make install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Or you can try telling CMake to make a package for you.  For Debian it is:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 $ cpack -G DEB
 | 
				
			||||||
 | 
					 # dpkg -i wdmtg-*.deb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Contributing and Support
 | 
				
			||||||
 | 
					------------------------
 | 
				
			||||||
 | 
					Use this project's GitHub to report any bugs, request features, or submit pull
 | 
				
			||||||
 | 
					requests.  If you want to discuss this project, or maybe just hang out with
 | 
				
			||||||
 | 
					the developer, feel free to join me at irc://irc.janouch.name, channel #dev.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					License
 | 
				
			||||||
 | 
					-------
 | 
				
			||||||
 | 
					'wdmtg' is written by Přemysl Janouch <p.janouch@gmail.com>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					You may use the software under the terms of the ISC license, the text of which
 | 
				
			||||||
 | 
					is included within the package, or, at your option, you may relicense the work
 | 
				
			||||||
 | 
					under the MIT or the Modified BSD License, as listed at the following site:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					http://www.gnu.org/licenses/license-list.html
 | 
				
			||||||
							
								
								
									
										47
									
								
								cmake/FindVala.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								cmake/FindVala.cmake
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					# - Find Vala
 | 
				
			||||||
 | 
					# This module looks for valac.
 | 
				
			||||||
 | 
					# This module defines the following values:
 | 
				
			||||||
 | 
					#    VALA_FOUND
 | 
				
			||||||
 | 
					#    VALA_COMPILER
 | 
				
			||||||
 | 
					#    VALA_VERSION
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#=============================================================================
 | 
				
			||||||
 | 
					# Copyright Přemysl Janouch 2011
 | 
				
			||||||
 | 
					# All rights reserved.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
 | 
					# modification, are permitted provided that the following conditions are met:
 | 
				
			||||||
 | 
					#     * Redistributions of source code must retain the above copyright
 | 
				
			||||||
 | 
					#       notice, this list of conditions and the following disclaimer.
 | 
				
			||||||
 | 
					#     * Redistributions in binary form must reproduce the above copyright
 | 
				
			||||||
 | 
					#       notice, this list of conditions and the following disclaimer in the
 | 
				
			||||||
 | 
					#       documentation and/or other materials provided with the distribution.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
 | 
				
			||||||
 | 
					# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | 
				
			||||||
 | 
					# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | 
				
			||||||
 | 
					# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
 | 
				
			||||||
 | 
					# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
				
			||||||
 | 
					# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
				
			||||||
 | 
					# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
				
			||||||
 | 
					# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
				
			||||||
 | 
					# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 | 
				
			||||||
 | 
					# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 | 
				
			||||||
 | 
					# OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					#=============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					find_program (VALA_COMPILER "valac")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (VALA_COMPILER)
 | 
				
			||||||
 | 
						execute_process (COMMAND ${VALA_COMPILER} --version
 | 
				
			||||||
 | 
							OUTPUT_VARIABLE VALA_VERSION)
 | 
				
			||||||
 | 
						string (REGEX MATCH "[.0-9]+" VALA_VERSION "${VALA_VERSION}")
 | 
				
			||||||
 | 
					endif (VALA_COMPILER)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include (FindPackageHandleStandardArgs)
 | 
				
			||||||
 | 
					FIND_PACKAGE_HANDLE_STANDARD_ARGS (Vala
 | 
				
			||||||
 | 
						REQUIRED_VARS VALA_COMPILER
 | 
				
			||||||
 | 
						VERSION_VAR VALA_VERSION)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mark_as_advanced (VALA_COMPILER VALA_VERSION)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										205
									
								
								cmake/ValaPrecompile.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										205
									
								
								cmake/ValaPrecompile.cmake
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,205 @@
 | 
				
			|||||||
 | 
					# - Precompilation of Vala/Genie source files into C sources
 | 
				
			||||||
 | 
					# Makes use of the parallel build ability introduced in Vala 0.11. Derived
 | 
				
			||||||
 | 
					# from a similar module by Jakob Westhoff and the original GNU Make rules.
 | 
				
			||||||
 | 
					# Might be a bit oversimplified.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This module defines three functions. The first one:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   vala_init (id
 | 
				
			||||||
 | 
					#     [DIRECTORY dir]          - Output directory (binary dir by default)
 | 
				
			||||||
 | 
					#     [PACKAGES package...]    - Package dependencies
 | 
				
			||||||
 | 
					#     [OPTIONS option...]      - Extra valac options
 | 
				
			||||||
 | 
					#     [CUSTOM_VAPIS file...])  - Custom vapi files to include in the build
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# initializes a single precompilation unit using the given arguments.
 | 
				
			||||||
 | 
					# You can put files into it via the following function:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   vala_add (id source.vala
 | 
				
			||||||
 | 
					#     [DEPENDS source...])     - Vala/Genie source or .vapi dependencies
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Finally retrieve paths for generated C files by calling:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   vala_finish (id
 | 
				
			||||||
 | 
					#     [SOURCES sources_var]          - Input Vala/Genie sources
 | 
				
			||||||
 | 
					#     [OUTPUTS outputs_var]          - Output C sources
 | 
				
			||||||
 | 
					#     [GENERATE_HEADER id.h          - Generate id.h and id_internal.h
 | 
				
			||||||
 | 
					#       [GENERATE_VAPI id.vapi]      - Generate a vapi file
 | 
				
			||||||
 | 
					#       [GENERATE_SYMBOLS id.def]])  - Generate a list of public symbols
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#=============================================================================
 | 
				
			||||||
 | 
					# Copyright Přemysl Janouch 2011
 | 
				
			||||||
 | 
					# All rights reserved.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
 | 
					# modification, are permitted provided that the following conditions are met:
 | 
				
			||||||
 | 
					#     * Redistributions of source code must retain the above copyright
 | 
				
			||||||
 | 
					#       notice, this list of conditions and the following disclaimer.
 | 
				
			||||||
 | 
					#     * Redistributions in binary form must reproduce the above copyright
 | 
				
			||||||
 | 
					#       notice, this list of conditions and the following disclaimer in the
 | 
				
			||||||
 | 
					#       documentation and/or other materials provided with the distribution.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
 | 
				
			||||||
 | 
					# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 | 
				
			||||||
 | 
					# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | 
				
			||||||
 | 
					# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
 | 
				
			||||||
 | 
					# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | 
				
			||||||
 | 
					# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 | 
				
			||||||
 | 
					# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 | 
				
			||||||
 | 
					# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 | 
				
			||||||
 | 
					# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 | 
				
			||||||
 | 
					# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 | 
				
			||||||
 | 
					# OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					#=============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					find_package (Vala 0.11 REQUIRED)
 | 
				
			||||||
 | 
					include (CMakeParseArguments)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function (vala_init id)
 | 
				
			||||||
 | 
						set (_multi_value PACKAGES OPTIONS CUSTOM_VAPIS)
 | 
				
			||||||
 | 
						cmake_parse_arguments (arg "" "DIRECTORY" "${_multi_value}" ${ARGN})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg_DIRECTORY)
 | 
				
			||||||
 | 
							set (directory ${arg_DIRECTORY})
 | 
				
			||||||
 | 
							if (NOT IS_DIRECTORY ${directory})
 | 
				
			||||||
 | 
								file (MAKE_DIRECTORY ${directory})
 | 
				
			||||||
 | 
							endif (NOT IS_DIRECTORY ${directory})
 | 
				
			||||||
 | 
						else (arg_DIRECTORY)
 | 
				
			||||||
 | 
							set (directory ${CMAKE_CURRENT_BINARY_DIR})
 | 
				
			||||||
 | 
						endif (arg_DIRECTORY)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set (pkg_opts)
 | 
				
			||||||
 | 
						foreach (pkg ${arg_PACKAGES})
 | 
				
			||||||
 | 
							list (APPEND pkg_opts "--pkg=${pkg}")
 | 
				
			||||||
 | 
						endforeach (pkg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set (VALA_${id}_DIR "${directory}" PARENT_SCOPE)
 | 
				
			||||||
 | 
						set (VALA_${id}_ARGS ${pkg_opts} ${arg_OPTIONS}
 | 
				
			||||||
 | 
							${arg_CUSTOM_VAPIS} PARENT_SCOPE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set (VALA_${id}_SOURCES "" PARENT_SCOPE)
 | 
				
			||||||
 | 
						set (VALA_${id}_OUTPUTS "" PARENT_SCOPE)
 | 
				
			||||||
 | 
						set (VALA_${id}_FAST_VAPI_FILES "" PARENT_SCOPE)
 | 
				
			||||||
 | 
						set (VALA_${id}_FAST_VAPI_ARGS "" PARENT_SCOPE)
 | 
				
			||||||
 | 
					endfunction (vala_init)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function (vala_add id file)
 | 
				
			||||||
 | 
						cmake_parse_arguments (arg "" "" "DEPENDS" ${ARGN})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (NOT IS_ABSOLUTE "${file}")
 | 
				
			||||||
 | 
							set (file "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
 | 
				
			||||||
 | 
						endif (NOT IS_ABSOLUTE "${file}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						get_filename_component (output_name "${file}" NAME)
 | 
				
			||||||
 | 
						get_filename_component (output_base "${file}" NAME_WE)
 | 
				
			||||||
 | 
						set (output_base "${VALA_${id}_DIR}/${output_base}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# XXX: It would be best to have it working without touching the vapi
 | 
				
			||||||
 | 
						#      but it appears this cannot be done in CMake.
 | 
				
			||||||
 | 
						add_custom_command (OUTPUT "${output_base}.vapi"
 | 
				
			||||||
 | 
							COMMAND ${VALA_COMPILER} "${file}" "--fast-vapi=${output_base}.vapi"
 | 
				
			||||||
 | 
							COMMAND ${CMAKE_COMMAND} -E touch "${output_base}.vapi"
 | 
				
			||||||
 | 
							DEPENDS "${file}"
 | 
				
			||||||
 | 
							COMMENT "Generating a fast vapi for ${output_name}" VERBATIM)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set (vapi_opts)
 | 
				
			||||||
 | 
						set (vapi_depends)
 | 
				
			||||||
 | 
						foreach (vapi ${arg_DEPENDS})
 | 
				
			||||||
 | 
							if (NOT IS_ABSOLUTE "${vapi}")
 | 
				
			||||||
 | 
								set (vapi "${VALA_${id}_DIR}/${vapi}.vapi")
 | 
				
			||||||
 | 
							endif (NOT IS_ABSOLUTE "${vapi}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							list (APPEND vapi_opts "--use-fast-vapi=${vapi}")
 | 
				
			||||||
 | 
							list (APPEND vapi_depends "${vapi}")
 | 
				
			||||||
 | 
						endforeach (vapi)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						add_custom_command (OUTPUT "${output_base}.c"
 | 
				
			||||||
 | 
							COMMAND ${VALA_COMPILER} "${file}" -C ${vapi_opts} ${VALA_${id}_ARGS}
 | 
				
			||||||
 | 
							COMMAND ${CMAKE_COMMAND} -E touch "${output_base}.c"
 | 
				
			||||||
 | 
							DEPENDS "${file}" ${vapi_depends}
 | 
				
			||||||
 | 
							WORKING_DIRECTORY "${VALA_${id}_DIR}"
 | 
				
			||||||
 | 
							COMMENT "Precompiling ${output_name}" VERBATIM)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set (VALA_${id}_SOURCES ${VALA_${id}_SOURCES}
 | 
				
			||||||
 | 
							"${file}" PARENT_SCOPE)
 | 
				
			||||||
 | 
						set (VALA_${id}_OUTPUTS ${VALA_${id}_OUTPUTS}
 | 
				
			||||||
 | 
							"${output_base}.c" PARENT_SCOPE)
 | 
				
			||||||
 | 
						set (VALA_${id}_FAST_VAPI_FILES ${VALA_${id}_FAST_VAPI_FILES}
 | 
				
			||||||
 | 
							"${output_base}.vapi" PARENT_SCOPE)
 | 
				
			||||||
 | 
						set (VALA_${id}_FAST_VAPI_ARGS ${VALA_${id}_FAST_VAPI_ARGS}
 | 
				
			||||||
 | 
							"--use-fast-vapi=${output_base}.vapi" PARENT_SCOPE)
 | 
				
			||||||
 | 
					endfunction (vala_add)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function (vala_finish id)
 | 
				
			||||||
 | 
						set (_one_value SOURCES OUTPUTS
 | 
				
			||||||
 | 
							GENERATE_VAPI GENERATE_HEADER GENERATE_SYMBOLS)
 | 
				
			||||||
 | 
						cmake_parse_arguments (arg "" "${_one_value}" "" ${ARGN})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg_SOURCES)
 | 
				
			||||||
 | 
							set (${arg_SOURCES} ${VALA_${id}_SOURCES} PARENT_SCOPE)
 | 
				
			||||||
 | 
						endif (arg_SOURCES)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg_OUTPUTS)
 | 
				
			||||||
 | 
							set (${arg_OUTPUTS} ${VALA_${id}_OUTPUTS} PARENT_SCOPE)
 | 
				
			||||||
 | 
						endif (arg_OUTPUTS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set (outputs)
 | 
				
			||||||
 | 
						set (export_args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg_GENERATE_VAPI)
 | 
				
			||||||
 | 
							if (NOT IS_ABSOLUTE "${arg_GENERATE_VAPI}")
 | 
				
			||||||
 | 
								set (arg_GENERATE_VAPI
 | 
				
			||||||
 | 
									"${VALA_${id}_DIR}/${arg_GENERATE_VAPI}")
 | 
				
			||||||
 | 
							endif (NOT IS_ABSOLUTE "${arg_GENERATE_VAPI}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							list (APPEND outputs "${arg_GENERATE_VAPI}")
 | 
				
			||||||
 | 
							list (APPEND export_args "--internal-vapi=${arg_GENERATE_VAPI}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (NOT arg_GENERATE_HEADER)
 | 
				
			||||||
 | 
								message (FATAL_ERROR "Header generation required for vapi")
 | 
				
			||||||
 | 
							endif (NOT arg_GENERATE_HEADER)
 | 
				
			||||||
 | 
						endif (arg_GENERATE_VAPI)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg_GENERATE_SYMBOLS)
 | 
				
			||||||
 | 
							if (NOT IS_ABSOLUTE "${arg_GENERATE_SYMBOLS}")
 | 
				
			||||||
 | 
								set (arg_GENERATE_SYMBOLS
 | 
				
			||||||
 | 
									"${VALA_${id}_DIR}/${arg_GENERATE_SYMBOLS}")
 | 
				
			||||||
 | 
							endif (NOT IS_ABSOLUTE "${arg_GENERATE_SYMBOLS}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							list (APPEND outputs "${arg_GENERATE_SYMBOLS}")
 | 
				
			||||||
 | 
							list (APPEND export_args "--symbols=${arg_GENERATE_SYMBOLS}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (NOT arg_GENERATE_HEADER)
 | 
				
			||||||
 | 
								message (FATAL_ERROR "Header generation required for symbols")
 | 
				
			||||||
 | 
							endif (NOT arg_GENERATE_HEADER)
 | 
				
			||||||
 | 
						endif (arg_GENERATE_SYMBOLS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (arg_GENERATE_HEADER)
 | 
				
			||||||
 | 
							if (NOT IS_ABSOLUTE "${arg_GENERATE_HEADER}")
 | 
				
			||||||
 | 
								set (arg_GENERATE_HEADER
 | 
				
			||||||
 | 
									"${VALA_${id}_DIR}/${arg_GENERATE_HEADER}")
 | 
				
			||||||
 | 
							endif (NOT IS_ABSOLUTE "${arg_GENERATE_HEADER}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							get_filename_component (header_path "${arg_GENERATE_HEADER}" PATH)
 | 
				
			||||||
 | 
							get_filename_component (header_name "${arg_GENERATE_HEADER}" NAME_WE)
 | 
				
			||||||
 | 
							set (header_base "${header_path}/${header_name}")
 | 
				
			||||||
 | 
							get_filename_component (header_ext "${arg_GENERATE_HEADER}" EXT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							list (APPEND outputs
 | 
				
			||||||
 | 
								"${header_base}${header_ext}"
 | 
				
			||||||
 | 
								"${header_base}_internal${header_ext}")
 | 
				
			||||||
 | 
							list (APPEND export_args
 | 
				
			||||||
 | 
								"--header=${header_base}${header_ext}"
 | 
				
			||||||
 | 
								"--internal-header=${header_base}_internal${header_ext}")
 | 
				
			||||||
 | 
						endif (arg_GENERATE_HEADER)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (outputs)
 | 
				
			||||||
 | 
							add_custom_command (OUTPUT ${outputs}
 | 
				
			||||||
 | 
								COMMAND ${VALA_COMPILER} -C ${VALA_${id}_ARGS}
 | 
				
			||||||
 | 
									${export_args} ${VALA_${id}_FAST_VAPI_ARGS}
 | 
				
			||||||
 | 
								DEPENDS ${VALA_${id}_FAST_VAPI_FILES}
 | 
				
			||||||
 | 
								COMMENT "Generating vapi/headers/symbols" VERBATIM)
 | 
				
			||||||
 | 
						endif (outputs)
 | 
				
			||||||
 | 
					endfunction (vala_finish id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										8
									
								
								config.vala.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								config.vala.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					[CCode (cprefix = "", lower_case_cprefix = "")]
 | 
				
			||||||
 | 
					namespace Config
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						public const string PROJECT_NAME = "${CMAKE_PROJECT_NAME}";
 | 
				
			||||||
 | 
						public const string PROJECT_VERSION = "${project_VERSION_MAJOR}.${project_VERSION_MINOR}.${project_VERSION_PATCH}";
 | 
				
			||||||
 | 
						public const string SHARE_DIR = "@project_SHARE_DIR@";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										288
									
								
								wdmtg.vala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										288
									
								
								wdmtg.vala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,288 @@
 | 
				
			|||||||
 | 
					//
 | 
				
			||||||
 | 
					// wdmtg.vala: activity tracker
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Copyright (c) 2016, Přemysl Janouch <p.janouch@gmail.com>
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 | 
					// purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					// copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 | 
				
			||||||
 | 
					// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 | 
				
			||||||
 | 
					// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 | 
				
			||||||
 | 
					// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// vim: set sw=2 ts=2 sts=2 et tw=80:
 | 
				
			||||||
 | 
					// modules: x11 xsync config
 | 
				
			||||||
 | 
					// vapidirs: . ../build build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Wdmtg {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// --- Utilities ---------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void exit_fatal (string format, ...) {
 | 
				
			||||||
 | 
					    stderr.vprintf ("fatal: " + format + "\n", va_list ());
 | 
				
			||||||
 | 
					    Process.exit (1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  string[] get_xdg_config_dirs () {
 | 
				
			||||||
 | 
					    string[] paths = { Environment.get_user_config_dir () };
 | 
				
			||||||
 | 
					    foreach (var system_path in Environment.get_system_config_dirs ())
 | 
				
			||||||
 | 
					      paths += system_path;
 | 
				
			||||||
 | 
					    return paths;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// --- Globals -----------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  X.Display dpy;                        ///< X display handle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  X.ID idle_counter;                    ///< XSync IDLETIME counter
 | 
				
			||||||
 | 
					  X.Sync.Value idle_timeout;            ///< User idle timeout
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  X.ID idle_alarm_inactive;             ///< User is inactive
 | 
				
			||||||
 | 
					  X.ID idle_alarm_active;               ///< User is active
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  X.Atom net_active_window;             ///< _NET_ACTIVE_WINDOW atom
 | 
				
			||||||
 | 
					  X.Atom net_wm_name;                   ///< _NET_WM_NAME atom
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  string? current_title;                ///< Current window title
 | 
				
			||||||
 | 
					  X.Window current_window;              ///< Current window
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// --- X helpers ---------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  X.ID get_counter (string name) {
 | 
				
			||||||
 | 
					    int n_counters = 0;
 | 
				
			||||||
 | 
					    var counters = X.Sync.list_system_counters (dpy, out n_counters);
 | 
				
			||||||
 | 
					    X.ID counter = X.None;
 | 
				
			||||||
 | 
					    while (n_counters-- > 0) {
 | 
				
			||||||
 | 
					      if (counters[n_counters].name == name)
 | 
				
			||||||
 | 
					        counter = counters[n_counters].counter;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    X.Sync.free_system_counter_list (counters);
 | 
				
			||||||
 | 
					    return counter;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  string? x_text_property_to_utf8 (ref X.TextProperty prop) {
 | 
				
			||||||
 | 
					    X.Atom utf8_string = dpy.intern_atom ("UTF8_STRING", true);
 | 
				
			||||||
 | 
					    if (prop.encoding == utf8_string)
 | 
				
			||||||
 | 
					      return (string) prop.value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int n = 0;
 | 
				
			||||||
 | 
					    uint8 **list = null;
 | 
				
			||||||
 | 
					    if (X.mb_text_property_to_text_list (dpy, ref prop, out list, out n)
 | 
				
			||||||
 | 
					      >= X.Success && n > 0 && null != list[0]) {
 | 
				
			||||||
 | 
					      var result = ((string) list[0]).locale_to_utf8 (-1, null, null);
 | 
				
			||||||
 | 
					      X.free_string_list (list);
 | 
				
			||||||
 | 
					      return result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  string? x_text_property (X.Window window, X.Atom atom) {
 | 
				
			||||||
 | 
					    X.TextProperty name;
 | 
				
			||||||
 | 
					    X.get_text_property (dpy, window, out name, atom);
 | 
				
			||||||
 | 
					    if (null == name.@value)
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    string? result = x_text_property_to_utf8 (ref name);
 | 
				
			||||||
 | 
					    X.free (name.@value);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// --- X error handling --------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  X.ErrorHandler default_x_error_handler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int on_x_error (X.Display dpy, X.ErrorEvent *ee) {
 | 
				
			||||||
 | 
					    // This just is going to happen since those windows aren't ours
 | 
				
			||||||
 | 
					    if (ee.error_code == X.ErrorCode.BAD_WINDOW)
 | 
				
			||||||
 | 
					      return 0;
 | 
				
			||||||
 | 
					    return default_x_error_handler (dpy, ee);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// --- Application -------------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  string x_window_title (X.Window window) {
 | 
				
			||||||
 | 
					    string? title;
 | 
				
			||||||
 | 
					    if (null == (title = x_text_property (window, net_wm_name))
 | 
				
			||||||
 | 
					     && null == (title = x_text_property (window, X.XA_WM_NAME)))
 | 
				
			||||||
 | 
					      title = "broken";
 | 
				
			||||||
 | 
					    return title;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool update_window_title (string? new_title) {
 | 
				
			||||||
 | 
					    bool changed = (null == current_title) != (null == new_title)
 | 
				
			||||||
 | 
					      || current_title != new_title;
 | 
				
			||||||
 | 
					    current_title = new_title;
 | 
				
			||||||
 | 
					    return changed;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void update_current_window () {
 | 
				
			||||||
 | 
					    var root = dpy.default_root_window ();
 | 
				
			||||||
 | 
					    X.Atom dummy_type; int dummy_format; ulong nitems, dummy_bytes;
 | 
				
			||||||
 | 
					    void *p = null;
 | 
				
			||||||
 | 
					    if (dpy.get_window_property (root, net_active_window,
 | 
				
			||||||
 | 
					      0, 1, false, X.XA_WINDOW, out dummy_type, out dummy_format,
 | 
				
			||||||
 | 
					      out nitems, out dummy_bytes, out p) != X.Success)
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    string? new_title = null;
 | 
				
			||||||
 | 
					    if (0 != nitems) {
 | 
				
			||||||
 | 
					      X.Window active_window = *(X.Window *) p;
 | 
				
			||||||
 | 
					      X.free (p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (current_window != active_window && X.None != current_window)
 | 
				
			||||||
 | 
					        dpy.select_input (current_window, 0);
 | 
				
			||||||
 | 
					      dpy.select_input (active_window, X.EventMask.PropertyChangeMask);
 | 
				
			||||||
 | 
					      new_title = x_window_title (active_window);
 | 
				
			||||||
 | 
					      current_window = active_window;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (update_window_title (new_title))
 | 
				
			||||||
 | 
					      stdout.printf ("Window changed: %s\n",
 | 
				
			||||||
 | 
					        null != current_title ? current_title : "(none)");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void on_x_property_notify (X.PropertyEvent *xproperty) {
 | 
				
			||||||
 | 
					    // This is from the EWMH specification, set by the window manager
 | 
				
			||||||
 | 
					    if (xproperty.atom == net_active_window)
 | 
				
			||||||
 | 
					      update_current_window ();
 | 
				
			||||||
 | 
					    else if (xproperty.window == current_window
 | 
				
			||||||
 | 
					      && xproperty.atom == net_wm_name) {
 | 
				
			||||||
 | 
					      if (update_window_title (x_window_title (current_window)))
 | 
				
			||||||
 | 
					        stdout.printf ("Title changed: %s\n", current_title);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void set_idle_alarm
 | 
				
			||||||
 | 
					    (ref X.ID alarm, X.Sync.TestType test, X.Sync.Value @value) {
 | 
				
			||||||
 | 
					    X.Sync.AlarmAttributes attr = {};
 | 
				
			||||||
 | 
					    attr.trigger.counter = idle_counter;
 | 
				
			||||||
 | 
					    attr.trigger.test_type = test;
 | 
				
			||||||
 | 
					    attr.trigger.wait_value = @value;
 | 
				
			||||||
 | 
					    X.Sync.int_to_value (out attr.delta, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    X.Sync.CA flags = X.Sync.CA.Counter | X.Sync.CA.TestType
 | 
				
			||||||
 | 
					      | X.Sync.CA.Value | X.Sync.CA.Delta;
 | 
				
			||||||
 | 
					    if (X.None != alarm)
 | 
				
			||||||
 | 
					      X.Sync.change_alarm (dpy, alarm, flags, ref attr);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      alarm = X.Sync.create_alarm (dpy, flags, ref attr);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void on_x_alarm_notify (X.Sync.AlarmNotifyEvent *xalarm) {
 | 
				
			||||||
 | 
					    if (xalarm.alarm == idle_alarm_inactive) {
 | 
				
			||||||
 | 
					      stdout.printf ("User is inactive\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      X.Sync.Value one, minus_one;
 | 
				
			||||||
 | 
					      X.Sync.int_to_value (out one, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      int overflow;
 | 
				
			||||||
 | 
					      X.Sync.value_subtract
 | 
				
			||||||
 | 
					        (out minus_one, xalarm.counter_value, one, out overflow);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Set an alarm for IDLETIME <= current_idletime - 1
 | 
				
			||||||
 | 
					      set_idle_alarm (ref idle_alarm_active,
 | 
				
			||||||
 | 
					        X.Sync.TestType.NegativeComparison, minus_one);
 | 
				
			||||||
 | 
					    } else if (xalarm.alarm == idle_alarm_inactive) {
 | 
				
			||||||
 | 
					      stdout.printf ("User is active\n");
 | 
				
			||||||
 | 
					      set_idle_alarm (ref idle_alarm_inactive,
 | 
				
			||||||
 | 
					        X.Sync.TestType.PositiveComparison, idle_timeout);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool show_version;
 | 
				
			||||||
 | 
					  const OptionEntry[] options = {
 | 
				
			||||||
 | 
					    { "version", 'V', OptionFlags.IN_MAIN, OptionArg.NONE, ref show_version,
 | 
				
			||||||
 | 
					      "output version information and exit" },
 | 
				
			||||||
 | 
					    { null }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public int main (string[] args) {
 | 
				
			||||||
 | 
					    if (null == Intl.setlocale (GLib.LocaleCategory.CTYPE))
 | 
				
			||||||
 | 
					      exit_fatal ("cannot set locale");
 | 
				
			||||||
 | 
					    if (0 == X.supports_locale ())
 | 
				
			||||||
 | 
					      exit_fatal ("locale not supported by Xlib");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      var ctx = new OptionContext (" - activity tracker");
 | 
				
			||||||
 | 
					      ctx.set_help_enabled (true);
 | 
				
			||||||
 | 
					      ctx.add_main_entries (options, null);
 | 
				
			||||||
 | 
					      ctx.parse (ref args);
 | 
				
			||||||
 | 
					    } catch (OptionError e) {
 | 
				
			||||||
 | 
					      exit_fatal ("option parsing failed: %s", e.message);
 | 
				
			||||||
 | 
					      return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (show_version) {
 | 
				
			||||||
 | 
					      stdout.printf (Config.PROJECT_NAME + " " + Config.PROJECT_VERSION + "\n");
 | 
				
			||||||
 | 
					      return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    X.init_threads ();
 | 
				
			||||||
 | 
					    if (null == (dpy = new X.Display ()))
 | 
				
			||||||
 | 
					      exit_fatal ("cannot open display");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    net_active_window = dpy.intern_atom ("_NET_ACTIVE_WINDOW", true);
 | 
				
			||||||
 | 
					    net_wm_name       = dpy.intern_atom ("_NET_WM_NAME", true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO: it is possible to employ a fallback mechanism via XScreenSaver
 | 
				
			||||||
 | 
					    //   by polling the XScreenSaverInfo::idle field, see
 | 
				
			||||||
 | 
					    //   https://www.x.org/releases/X11R7.5/doc/man/man3/Xss.3.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int sync_base, dummy;
 | 
				
			||||||
 | 
					    if (0 == X.Sync.query_extension (dpy, out sync_base, out dummy)
 | 
				
			||||||
 | 
					     || 0 == X.Sync.initialize (dpy, out dummy, out dummy))
 | 
				
			||||||
 | 
					      exit_fatal ("cannot initialize XSync");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // The idle counter is not guaranteed to exist, only SERVERTIME is
 | 
				
			||||||
 | 
					    if (X.None == (idle_counter = get_counter ("IDLETIME")))
 | 
				
			||||||
 | 
					      exit_fatal ("idle counter is missing");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var root = dpy.default_root_window ();
 | 
				
			||||||
 | 
					    dpy.select_input (root, X.EventMask.PropertyChangeMask);
 | 
				
			||||||
 | 
					    X.sync (dpy, false);
 | 
				
			||||||
 | 
					    default_x_error_handler = X.set_error_handler (on_x_error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int timeout = 600;  // 10 minutes by default
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      var kf = new KeyFile ();
 | 
				
			||||||
 | 
					      kf.load_from_dirs (Config.PROJECT_NAME + Path.DIR_SEPARATOR_S
 | 
				
			||||||
 | 
					        + Config.PROJECT_NAME + ".conf", get_xdg_config_dirs (), null, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      var n = kf.get_uint64 ("Settings", "idle_timeout");
 | 
				
			||||||
 | 
					      if (0 != n && n <= int.MAX / 1000)
 | 
				
			||||||
 | 
					        timeout = (int) n;
 | 
				
			||||||
 | 
					    } catch (Error e) {
 | 
				
			||||||
 | 
					      // Ignore errors this far, keeping the defaults
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    X.Sync.int_to_value (out idle_timeout, timeout * 1000);
 | 
				
			||||||
 | 
					    update_current_window ();
 | 
				
			||||||
 | 
					    set_idle_alarm (ref idle_alarm_inactive,
 | 
				
			||||||
 | 
					      X.Sync.TestType.PositiveComparison, idle_timeout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var loop = new MainLoop ();
 | 
				
			||||||
 | 
					    var channel = new IOChannel.unix_new (dpy.connection_number ());
 | 
				
			||||||
 | 
					    channel.add_watch (IOCondition.IN, (source, condition) => {
 | 
				
			||||||
 | 
					      if (0 == (condition & IOCondition.IN))
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      X.Event ev = {0};
 | 
				
			||||||
 | 
					      while (0 != dpy.pending ()) {
 | 
				
			||||||
 | 
					        if (0 != dpy.next_event (ref ev)) {
 | 
				
			||||||
 | 
					          exit_fatal ("XNextEvent returned non-zero");
 | 
				
			||||||
 | 
					        } else if (ev.type == X.EventType.PropertyNotify) {
 | 
				
			||||||
 | 
					          on_x_property_notify (&ev.xproperty);
 | 
				
			||||||
 | 
					        } else if (ev.type == sync_base + X.Sync.EventType.AlarmNotify) {
 | 
				
			||||||
 | 
					          on_x_alarm_notify ((X.Sync.AlarmNotifyEvent *) (&ev));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return true;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    loop.run ();
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										243
									
								
								xsync.vapi
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								xsync.vapi
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,243 @@
 | 
				
			|||||||
 | 
					//
 | 
				
			||||||
 | 
					// xsync.vapi: selected XSync APIs
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Copyright (c) 2016, Přemysl Janouch <p.janouch@gmail.com>
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Permission to use, copy, modify, and/or distribute this software for any
 | 
				
			||||||
 | 
					// purpose with or without fee is hereby granted, provided that the above
 | 
				
			||||||
 | 
					// copyright notice and this permission notice appear in all copies.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
				
			||||||
 | 
					// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 | 
				
			||||||
 | 
					// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
				
			||||||
 | 
					// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 | 
				
			||||||
 | 
					// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 | 
				
			||||||
 | 
					// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// vim: set sw=2 ts=2 sts=2 et tw=80:
 | 
				
			||||||
 | 
					// modules: x11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: move this outside, I didn't expect the Xlib binding to be this shitty
 | 
				
			||||||
 | 
					namespace X {
 | 
				
			||||||
 | 
					  [CCode (cname = "XErrorHandler", has_target = false)]
 | 
				
			||||||
 | 
					  public delegate int ErrorHandler (Display dpy, ErrorEvent *ee);
 | 
				
			||||||
 | 
					  [CCode (cname = "XSetErrorHandler")]
 | 
				
			||||||
 | 
					  public ErrorHandler set_error_handler (ErrorHandler handler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // XXX: can we extend the Display class so that the argument goes away?
 | 
				
			||||||
 | 
					  [CCode (cname = "XSync")]
 | 
				
			||||||
 | 
					  public int sync (Display dpy, bool discard);
 | 
				
			||||||
 | 
					  [CCode (cname = "XSupportsLocale")]
 | 
				
			||||||
 | 
					  public int supports_locale ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [CCode (cname = "XTextProperty", has_type_id = false)]
 | 
				
			||||||
 | 
					  public struct TextProperty {
 | 
				
			||||||
 | 
					    // There is always a null byte at the end but it may also appear earlier
 | 
				
			||||||
 | 
					    // depending on the other fields, so this is a bit misleading
 | 
				
			||||||
 | 
					    [CCode (array_null_terminated = true)]
 | 
				
			||||||
 | 
					    // Vala tries to g_free0() owned arrays, you still need to call XFree()
 | 
				
			||||||
 | 
					    public unowned uint8[]? @value;
 | 
				
			||||||
 | 
					    public Atom encoding;
 | 
				
			||||||
 | 
					    public int format;
 | 
				
			||||||
 | 
					    public ulong nitems;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  [CCode (cname = "XGetTextProperty")]
 | 
				
			||||||
 | 
					  public int get_text_property (Display dpy, Window window, out TextProperty text_prop_return, Atom property);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  [CCode (cname = "XmbTextPropertyToTextList")]
 | 
				
			||||||
 | 
					  public int mb_text_property_to_text_list (Display dpy, ref TextProperty text_prop, [CCode (type = "char ***")] out uint8 **list_return, out int count_return);
 | 
				
			||||||
 | 
					  [CCode (cname = "XFreeStringList")]
 | 
				
			||||||
 | 
					  public void free_string_list ([CCode (type = "char **")] uint8** list);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace X {
 | 
				
			||||||
 | 
					  [CCode (cprefix = "", cheader_filename = "X11/extensions/sync.h")]
 | 
				
			||||||
 | 
					  namespace Sync {
 | 
				
			||||||
 | 
					    [CCode (cprefix = "XSync", cname = "int", has_type_id = false)]
 | 
				
			||||||
 | 
					    public enum EventType {
 | 
				
			||||||
 | 
					      CounterNotify,
 | 
				
			||||||
 | 
					      AlarmNotify
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cprefix = "", cname = "int", has_type_id = false)]
 | 
				
			||||||
 | 
					    public enum ErrorCode {
 | 
				
			||||||
 | 
					      [CCode (cname = "XSyncBadCounter")]
 | 
				
			||||||
 | 
					      BAD_COUNTER,
 | 
				
			||||||
 | 
					      [CCode (cname = "XSyncBadAlarm")]
 | 
				
			||||||
 | 
					      BAD_ALARM,
 | 
				
			||||||
 | 
					      [CCode (cname = "XSyncBadFence")]
 | 
				
			||||||
 | 
					      BAD_FENCE
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cprefix = "XSyncCA", cname = "int")]
 | 
				
			||||||
 | 
					    [Flags]
 | 
				
			||||||
 | 
					    public enum CA {
 | 
				
			||||||
 | 
					      Counter,
 | 
				
			||||||
 | 
					      ValueType,
 | 
				
			||||||
 | 
					      Value,
 | 
				
			||||||
 | 
					      TestType,
 | 
				
			||||||
 | 
					      Delta,
 | 
				
			||||||
 | 
					      Events
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncValueType", cprefix = "XSync")]
 | 
				
			||||||
 | 
					    public enum ValueType {
 | 
				
			||||||
 | 
					      Absolute,
 | 
				
			||||||
 | 
					      Relative
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncTestType", cprefix = "XSync")]
 | 
				
			||||||
 | 
					    public enum TestType {
 | 
				
			||||||
 | 
					      PositiveTransition,
 | 
				
			||||||
 | 
					      NegativeTransition,
 | 
				
			||||||
 | 
					      PositiveComparison,
 | 
				
			||||||
 | 
					      NegativeComparison
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncAlarmState", cprefix = "XSyncAlarm")]
 | 
				
			||||||
 | 
					    public enum AlarmState {
 | 
				
			||||||
 | 
					      Active,
 | 
				
			||||||
 | 
					      Inactive,
 | 
				
			||||||
 | 
					      Destroyed
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncValue", has_type_id = false)]
 | 
				
			||||||
 | 
					    [SimpleType]
 | 
				
			||||||
 | 
					    public struct Value {
 | 
				
			||||||
 | 
					      public int hi;
 | 
				
			||||||
 | 
					      public uint lo;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncIntToValue")]
 | 
				
			||||||
 | 
					    public void int_to_value (out Value value, int v);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncIntsToValue")]
 | 
				
			||||||
 | 
					    public void ints_to_value (out Value value, uint l, int h);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncValueGreaterThan")]
 | 
				
			||||||
 | 
					    public int value_greater_than (Value a, Value b);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncValueLessThan")]
 | 
				
			||||||
 | 
					    public int value_less_than (Value a, Value b);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncValueGreaterOrEqual")]
 | 
				
			||||||
 | 
					    public int value_greater_or_equal (Value a, Value b);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncValueLessOrEqual")]
 | 
				
			||||||
 | 
					    public int value_less_or_equal (Value a, Value b);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncValueEqual")]
 | 
				
			||||||
 | 
					    public int value_equal (Value a, Value b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncValueIsNegative")]
 | 
				
			||||||
 | 
					    public int value_is_negative (Value a, Value b);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncValueIsZero")]
 | 
				
			||||||
 | 
					    public int value_is_zero (Value a, Value b);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncValueIsPositive")]
 | 
				
			||||||
 | 
					    public int value_is_positive (Value a, Value b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncValueLow32")]
 | 
				
			||||||
 | 
					    public uint value_low32 (Value value);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncValueHigh32")]
 | 
				
			||||||
 | 
					    public int value_high32 (Value value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncValueAdd")]
 | 
				
			||||||
 | 
					    public void value_add (out Value result, Value a, Value b, out int poverflow);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncValueSubtract")]
 | 
				
			||||||
 | 
					    public void value_subtract (out Value result, Value a, Value b, out int poverflow);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncMaxValue")]
 | 
				
			||||||
 | 
					    public void max_value (out Value pv);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncMinValue")]
 | 
				
			||||||
 | 
					    public void min_value (out Value pv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncSystemCounter", has_type_id = false)]
 | 
				
			||||||
 | 
					    public struct SystemCounter {
 | 
				
			||||||
 | 
					      public string name;
 | 
				
			||||||
 | 
					      public X.ID counter;
 | 
				
			||||||
 | 
					      public Value resolution;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncTrigger", has_type_id = false)]
 | 
				
			||||||
 | 
					    public struct Trigger {
 | 
				
			||||||
 | 
					      public X.ID counter;
 | 
				
			||||||
 | 
					      public ValueType value_type;
 | 
				
			||||||
 | 
					      public Value wait_value;
 | 
				
			||||||
 | 
					      public TestType test_type;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncWaitCondition", has_type_id = false)]
 | 
				
			||||||
 | 
					    public struct WaitCondition {
 | 
				
			||||||
 | 
					      public Trigger trigger;
 | 
				
			||||||
 | 
					      public Value event_threshold;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncAlarmAttributes", has_type_id = false)]
 | 
				
			||||||
 | 
					    public struct AlarmAttributes {
 | 
				
			||||||
 | 
					      public Trigger trigger;
 | 
				
			||||||
 | 
					      public Value delta;
 | 
				
			||||||
 | 
					      public int events;
 | 
				
			||||||
 | 
					      public AlarmState state;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncCounterNotifyEvent", has_type_id = false)]
 | 
				
			||||||
 | 
					    public struct CounterNotifyEvent {
 | 
				
			||||||
 | 
					      // TODO: other fields
 | 
				
			||||||
 | 
					      public X.ID counter;
 | 
				
			||||||
 | 
					      public Value wait_value;
 | 
				
			||||||
 | 
					      public Value counter_value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncAlarmNotifyEvent", has_type_id = false)]
 | 
				
			||||||
 | 
					    public struct AlarmNotifyEvent {
 | 
				
			||||||
 | 
					      // TODO: other fields
 | 
				
			||||||
 | 
					      public X.ID alarm;
 | 
				
			||||||
 | 
					      public Value counter_value;
 | 
				
			||||||
 | 
					      public Value alarm_value;
 | 
				
			||||||
 | 
					      public AlarmState state;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO: XSyncAlarmError
 | 
				
			||||||
 | 
					    // TODO: XSyncCounterError
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncQueryExtension")]
 | 
				
			||||||
 | 
					    public X.Status query_extension (X.Display dpy, out int event_base, out int error_base);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncInitialize")]
 | 
				
			||||||
 | 
					    public X.Status initialize (X.Display dpy, out int major_version, out int minor_version);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncListSystemCounters")]
 | 
				
			||||||
 | 
					    public SystemCounter *list_system_counters (X.Display dpy, out int n_counters);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncFreeSystemCounterList")]
 | 
				
			||||||
 | 
					    public void free_system_counter_list (SystemCounter *counters);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncCreateCounter")]
 | 
				
			||||||
 | 
					    public X.ID create_counter (X.Display dpy, Value initial_value);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncSetCounter")]
 | 
				
			||||||
 | 
					    public X.Status set_counter (X.Display dpy, X.ID counter, Value value);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncChangeCounter")]
 | 
				
			||||||
 | 
					    public X.Status change_counter (X.Display dpy, X.ID counter, Value value);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncDestroyCounter")]
 | 
				
			||||||
 | 
					    public X.Status destroy_counter (X.Display dpy, X.ID counter);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncQueryCounter")]
 | 
				
			||||||
 | 
					    public X.Status query_counter (X.Display dpy, X.ID counter, out Value value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncAwait")]
 | 
				
			||||||
 | 
					    public X.Status await (X.Display dpy, WaitCondition *wait_list, int n_conditions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncCreateAlarm")]
 | 
				
			||||||
 | 
					    public X.ID create_alarm (X.Display dpy, CA values_mask, ref AlarmAttributes values);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncDestroyAlarm")]
 | 
				
			||||||
 | 
					    public X.Status destroy_alarm (X.Display dpy, X.ID alarm);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncQueryAlarm")]
 | 
				
			||||||
 | 
					    public X.Status query_alarm (X.Display dpy, X.ID alarm, out AlarmAttributes values_return);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncChangeAlarm")]
 | 
				
			||||||
 | 
					    public X.Status change_alarm (X.Display dpy, X.ID alarm, CA values_mask, ref AlarmAttributes values);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncSetPriority")]
 | 
				
			||||||
 | 
					    public X.Status set_priority (X.Display dpy, X.ID alarm, int priority);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncGetPriority")]
 | 
				
			||||||
 | 
					    public X.Status get_priority (X.Display dpy, X.ID alarm, out int priority);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncCreateFence")]
 | 
				
			||||||
 | 
					    public X.ID create_fence (X.Display dpy, X.Drawable d, int initially_triggered);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncTriggerFence")]
 | 
				
			||||||
 | 
					    public int trigger_fence (X.Display dpy, X.ID fence);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncResetFence")]
 | 
				
			||||||
 | 
					    public int reset_fence (X.Display dpy, X.ID fence);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncDestroyFence")]
 | 
				
			||||||
 | 
					    public int destroy_fence (X.Display dpy, X.ID fence);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncQueryFence")]
 | 
				
			||||||
 | 
					    public int query_fence (X.Display dpy, X.ID fence, out int triggered);
 | 
				
			||||||
 | 
					    [CCode (cname = "XSyncAwaitFence")]
 | 
				
			||||||
 | 
					    public int await_fence (X.Display dpy, X.ID *fence_list, int n_fences);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user