summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Udaltsov <svu@gnome.org>2006-03-12 04:20:01 +0000
committerSergey Udaltsov <svu@gnome.org>2006-03-12 04:20:01 +0000
commit2c88cc80147b72eba939d6358939ef59d403c34e (patch)
treeb6b145f6d50e1f4bba8145bef5963aee8a5f3180
parentd7bc98fb5f9d55c37a08ceeedbc87cb70ee6f133 (diff)
downloadlibxklavier-2c88cc80147b72eba939d6358939ef59d403c34e.tar.gz
branching 2.x, merging GLIBing to HEAD
-rw-r--r--ChangeLog4
-rw-r--r--Doxyfile.in1162
-rw-r--r--Makefile.am13
-rwxr-xr-xautogen.sh5
-rw-r--r--configure.in19
-rw-r--r--doc/Makefile.am2
-rw-r--r--doc/html/.cvsignore1
-rw-r--r--doc/html/Makefile.am62
-rw-r--r--doc/reference/.cvsignore11
-rw-r--r--doc/reference/Makefile.am78
-rw-r--r--libxklavier.spec.in8
-rw-r--r--libxklavier/.indent.pro3
-rw-r--r--libxklavier/Makefile.am24
-rw-r--r--libxklavier/marshal.list3
-rw-r--r--libxklavier/xkl_config_item.h116
-rw-r--r--libxklavier/xkl_config_rec.h220
-rw-r--r--libxklavier/xkl_config_registry.h264
-rw-r--r--libxklavier/xkl_engine.h547
-rw-r--r--libxklavier/xkl_engine_marshal.c131
-rw-r--r--libxklavier/xkl_engine_marshal.h27
-rw-r--r--libxklavier/xklavier.c1402
-rw-r--r--libxklavier/xklavier.h573
-rw-r--r--libxklavier/xklavier_config.c1132
-rw-r--r--libxklavier/xklavier_config.h376
-rw-r--r--libxklavier/xklavier_config_i18n.c362
-rw-r--r--libxklavier/xklavier_config_xkb.c785
-rw-r--r--libxklavier/xklavier_config_xmm.c55
-rw-r--r--libxklavier/xklavier_dump.c433
-rw-r--r--libxklavier/xklavier_evt.c949
-rw-r--r--libxklavier/xklavier_evt_xkb.c228
-rw-r--r--libxklavier/xklavier_evt_xmm.c280
-rw-r--r--libxklavier/xklavier_private.h642
-rw-r--r--libxklavier/xklavier_private_xkb.h89
-rw-r--r--libxklavier/xklavier_private_xmm.h95
-rw-r--r--libxklavier/xklavier_props.c774
-rw-r--r--libxklavier/xklavier_toplevel.c343
-rw-r--r--libxklavier/xklavier_util.c436
-rw-r--r--libxklavier/xklavier_xkb.c936
-rwxr-xr-xlibxklavier/xklavier_xmm.c481
-rw-r--r--libxklavier/xklavier_xmm_opts.c222
-rw-r--r--tests/.indent.pro3
-rw-r--r--tests/Makefile.am4
-rw-r--r--tests/test_config.c400
-rw-r--r--tests/test_monitor.c187
44 files changed, 7201 insertions, 6686 deletions
diff --git a/ChangeLog b/ChangeLog
index 29d6aaa..f8069f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2006-03-12 svu
+
+ * everything: branching 2.x series, merging GLIBing branch to HEAD
+
2006-02-14 svu
* libxklavier/xklavier.c: libxklavier/xklavier_evt.c: hopefully fixing
diff --git a/Doxyfile.in b/Doxyfile.in
deleted file mode 100644
index 371a6a0..0000000
--- a/Doxyfile.in
+++ /dev/null
@@ -1,1162 +0,0 @@
-# Doxyfile 1.3.9.1
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-# TAG = value [value, ...]
-# For lists items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
-
-PROJECT_NAME = @PACKAGE@
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
-# if some version control system is used.
-
-PROJECT_NUMBER = @VERSION@
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY = doc
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of source
-# files, where putting all generated files in the same directory would otherwise
-# cause performance problems for the file system.
-
-CREATE_SUBDIRS = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
-# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
-# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
-# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
-# Swedish, and Ukrainian.
-
-OUTPUT_LANGUAGE = English
-
-# This tag can be used to specify the encoding used in the generated output.
-# The encoding is not always determined by the language that is chosen,
-# but also whether or not the output is meant for Windows or non-Windows users.
-# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
-# forces the Windows encoding (this is the default for the Windows binary),
-# whereas setting the tag to NO uses a Unix-style encoding (the default for
-# all platforms other than Windows).
-
-USE_WINDOWS_ENCODING = NO
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is used
-# as the annotated text. Otherwise, the brief description is used as-is. If left
-# blank, the following values are used ("$name" is automatically replaced with the
-# name of the entity): "The $name class" "The $name widget" "The $name file"
-# "is" "provides" "specifies" "contains" "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF =
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
-# description.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
-# members of a class in the documentation of that class as if those members were
-# ordinary class members. Constructors, destructors and assignment operators of
-# the base classes will not be shown.
-
-INLINE_INHERITED_MEMB = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
-# path to strip.
-
-STRIP_FROM_PATH =
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH =
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful is your file systems
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like the Qt-style comments (thus requiring an
-# explicit @brief command for a brief description.
-
-JAVADOC_AUTOBRIEF = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen
-# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member
-# documentation.
-
-DETAILS_AT_TOP = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
-# re-implements.
-
-INHERIT_DOCS = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE = 8
-
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
-# only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C = NO
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
-# only. Doxygen will then generate output that is more tailored for Java.
-# For instance, namespaces will be presented as packages, qualified scopes
-# will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
-# the \nosubgrouping command.
-
-SUBGROUPING = YES
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL = NO
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
-# will be included in the documentation.
-
-EXTRACT_PRIVATE = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
-
-EXTRACT_STATIC = NO
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES = YES
-
-# This flag is only useful for Objective-C code. When set to YES local
-# methods, which are defined in the implementation section but not in
-# the interface are included in the documentation.
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS = NO
-
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
-# of that file.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
-# is inserted in the documentation for inline members.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
-# declaration order.
-
-SORT_MEMBER_DOCS = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
-# brief documentation of file, namespace and class members alphabetically
-# by member name. If set to NO (the default) the members will appear in
-# declaration order.
-
-SORT_BRIEF_DOCS = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
-# sorted by fully-qualified names, including namespaces. If set to
-# NO (the default), the class list will be sorted only by class name,
-# not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
-# commands in the documentation.
-
-GENERATE_TODOLIST = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
-# commands in the documentation.
-
-GENERATE_TESTLIST = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
-# commands in the documentation.
-
-GENERATE_BUGLIST = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or define consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and defines in the
-# documentation can be controlled using \showinitializer or \hideinitializer
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES = YES
-
-# If the sources in your project are distributed over multiple directories
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
-# in the documentation.
-
-SHOW_DIRECTORIES = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
-# NO is used.
-
-WARNINGS = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED = YES
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR = YES
-
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text.
-
-WARN_FORMAT =
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
-# to stderr.
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
-# with spaces.
-
-INPUT = libxklavier
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
-# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
-
-FILE_PATTERNS = xklavier.h \
- xklavier_config.h
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
-# If left blank NO is used.
-
-RECURSIVE = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE =
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
-# that are symbolic links (a Unix filesystem feature) are excluded from the input.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories.
-
-EXCLUDE_PATTERNS =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
-# the \include command).
-
-EXAMPLE_PATH =
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
-
-EXAMPLE_PATTERNS =
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
-# the \image command).
-
-IMAGE_PATH =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output. If FILTER_PATTERNS is specified, this tag will be
-# ignored.
-
-INPUT_FILTER =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form:
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
-# is applied to all files.
-
-FILTER_PATTERNS =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-# Note: To get rid of all source code in the generated output, make sure also
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default)
-# then for each documented function all documented
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES (the default)
-# then for each documented function all documented entities
-# called/used by that function will be listed.
-
-REFERENCES_RELATION = YES
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX = NO
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
-# generate HTML output.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT =
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header.
-
-HTML_HEADER =
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
-
-HTML_FOOTER =
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet. Note that doxygen will try to copy
-# the style sheet file to the HTML output directory, so don't put your own
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET =
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
-# written to the html output directory.
-
-CHM_FILE =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it.
-
-DISABLE_INDEX = NO
-
-# This tag can be used to set the number of enum values (range [1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
-# probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
-# is shown.
-
-TREEVIEW_WIDTH = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
-# generate Latex output.
-
-GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT =
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
-# default command name.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, letter, legal and
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS = NO
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
-# higher quality PDF documentation.
-
-USE_PDFLATEX = NO
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
-# in the output.
-
-LATEX_HIDE_INDICES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimized for Word 97 and may not look very pretty with
-# other RTF readers or editors.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT =
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assignments. You only have to provide
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE =
-
-# Set optional variables used in the generation of an rtf document.
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
-# generate man pages
-
-GENERATE_MAN = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT =
-
-# The MAN_EXTENSION tag determines the extension that is added to
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION =
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
-# the code including all documentation.
-
-GENERATE_XML = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD =
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
-# dump the program listings (including syntax highlighting
-# and cross-referencing information) to the XML output. Note that
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
-# moment.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader. This is useful
-# if you want to understand what is going on. On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
-# files.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION = NO
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
-# PREDEFINED and EXPAND_AS_PREDEFINED tags.
-
-EXPAND_ONLY_PREDEF = NO
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
-# the preprocessor.
-
-INCLUDE_PATH =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
-# be used.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed. To prevent a macro definition from being
-# undefined via #undef or recursively expanded use the := operator
-# instead of the = operator.
-
-PREDEFINED =
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all function-like macros that are alone
-# on a line, have an all uppercase name, and do not end with a semicolon. Such
-# function macros are typically used for boiler-plate code, and will confuse the
-# parser if not removed.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles.
-# Optionally an initial location of the external documentation
-# can be added for each tagfile. The format of a tag file without
-# this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths or
-# URLs. If a location is present for each tag, the installdox tool
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
-# will be listed.
-
-ALLEXTERNALS = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
-# be listed.
-
-EXTERNAL_GROUPS = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or
-# super classes. Setting the tag to NO turns the diagrams off. Note that this
-# option is superseded by the HAVE_DOT option below. This is only a fallback. It is
-# recommended to install and use dot, since it yields more powerful graphs.
-
-CLASS_DIAGRAMS = YES
-
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT = NO
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-
-UML_LOOK = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS = NO
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
-# other documented files.
-
-INCLUDE_GRAPH = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
-# generate a call dependency graph for every global function or class method.
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command.
-
-CALL_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found on the path.
-
-DOT_PATH =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
-# \dotfile command).
-
-DOTFILE_DIRS =
-
-# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
-# large images.
-
-MAX_DOT_GRAPH_WIDTH = 1024
-
-# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
-# large images.
-
-MAX_DOT_GRAPH_HEIGHT = 1024
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
-# graphs generated by dot. A depth value of 3 means that only nodes reachable
-# from the root by following a path via at most 3 edges will be shown. Nodes that
-# lay further from the root node will be omitted. Note that setting this option to
-# 1 or 2 may greatly reduce the computation time needed for large code bases. Also
-# note that a graph may be further truncated if the graph's image dimensions are
-# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT).
-# If 0 is used for the depth value (the default), the graph is not depth-constrained.
-
-MAX_DOT_GRAPH_DEPTH = 0
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
-# the various graphs.
-
-DOT_CLEANUP = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE = NO
diff --git a/Makefile.am b/Makefile.am
index f531b81..0170b86 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,18 +4,9 @@ config_xml_DATA = xfree86.xml
config_xmldir = $(datadir)/$(PACKAGE)
EXTRA_DIST = libxklavier.spec libxklavier.spec.in \
- Doxyfile Doxyfile.in autogen.sh \
- CREDITS libxklavier.pc.in \
+ autogen.sh \
+ CREDITS libxklavier.pc.in gtk-doc.make \
$(config_xml_DATA)
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libxklavier.pc
-
-doxydocs: libxklavier/xklavier.h libxklavier/xklavier_config.h
- if test "x$(DO_DOXYGEN)" = "xyes" ; then \
- doxygen Doxyfile; \
- fi;
-
-all: doxydocs
-
-.PHONY: doxydocs
diff --git a/autogen.sh b/autogen.sh
index ad495e7..af16888 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -133,12 +133,15 @@ do
automake --add-missing --gnu $am_opt
echo "Running autoconf ..."
autoconf
+
+ echo "Running gtkdocize ..."
+ gtkdocize || exit 1
)
fi
done
#conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c
-conf_flags="--enable-doxygen"
+conf_flags="--enable-gtk-doc"
if test x$NOCONFIGURE = x; then
echo Running $srcdir/configure $conf_flags "$@" ...
diff --git a/configure.in b/configure.in
index c079adb..5bf0630 100644
--- a/configure.in
+++ b/configure.in
@@ -2,9 +2,9 @@ AC_INIT(libxklavier/xklavier.c)
PACKAGE=libxklavier
MAJOR_VERSION=2
-MINOR_VERSION=2
+MINOR_VERSION=91
VERSION=$MAJOR_VERSION.$MINOR_VERSION
-VERSION_INFO=10:0:0
+VERSION_INFO=11:0:0
AC_SUBST(MAJOR_VERSION)
AC_SUBST(MINOR_VERSION)
@@ -25,6 +25,7 @@ dnl AC_ARG_PROGRAM
AM_PROG_LIBTOOL
AM_ICONV
+GTK_DOC_CHECK(1.0)
dnl From Bruno Haible.
dnl From gnoome-vfs
@@ -101,12 +102,6 @@ AC_SUBST(xkbheaders_present)
CFLAGS="$save_CFLAGS"
-AC_ARG_ENABLE(doxygen,
-[ --enable-doxygen Build doxygen documentation],
-, enable_doxygen=no)
-
-AC_SUBST(DO_DOXYGEN,"${enable_doxygen}")
-
AC_ARG_ENABLE(xkb-support,
[ --enable-xkb-support Enable XKB support],
, enable_xkb_support=yes)
@@ -135,6 +130,11 @@ PKG_CHECK_MODULES(XML, \
AC_SUBST(XML_LIBS)
AC_SUBST(XML_CFLAGS)
+PKG_CHECK_MODULES(GLIB, \
+ glib-2.0 >= 2.6.0 gobject-2.0 >= 2.6.0)
+AC_SUBST(GLIB_LIBS)
+AC_SUBST(GLIB_CFLAGS)
+
AC_SUBST(CFLAGS)
AC_SUBST(LDFLAGS)
@@ -142,9 +142,8 @@ AC_OUTPUT([
Makefile
libxklavier/Makefile
libxklavier.spec
-Doxyfile
doc/Makefile
-doc/html/Makefile
+doc/reference/Makefile
tests/Makefile
libxklavier.pc
])
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 38d9a77..b68c774 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1 +1 @@
-SUBDIRS=html
+SUBDIRS=reference
diff --git a/doc/html/.cvsignore b/doc/html/.cvsignore
deleted file mode 100644
index 4414e3f..0000000
--- a/doc/html/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-Makefile Makefile.in *.html *.css *.gif *.png
diff --git a/doc/html/Makefile.am b/doc/html/Makefile.am
deleted file mode 100644
index ea274a8..0000000
--- a/doc/html/Makefile.am
+++ /dev/null
@@ -1,62 +0,0 @@
-EXTRA_WEB_FILES = doxygen.css \
- doxygen.png
-
-HTML_FILES = annotated.html\
- files.html\
- functions.html\
- globals.html\
- group__activation.html\
- group__callbacks.html\
- group__currents.html\
- group__debugerr.html\
- group__enum.html\
- group__lookup.html\
- group__props.html\
- group__settings.html\
- group__wininfo.html\
- group__xkbevents.html\
- group__xkbgroup.html\
- group__xkbinfo.html\
- group__xklconfig.html\
- group__xklconfiginitterm.html\
- group__xklinitterm.html\
- index.html\
- modules.html\
- struct__XklConfigItem.html\
- struct__XklConfigItem-members.html\
- struct__XklConfigRec.html\
- struct__XklConfigRec-members.html\
- structXklState.html\
- structXklState-members.html\
- xklavier_8h.html\
- xklavier_8h-source.html\
- xklavier__config_8h.html\
- xklavier__config_8h-source.html
-
-DOXYGEN_OUT_FILES = $(EXTRA_WEB_FILES) $(HTML_FILES)
-
-doc_to = $(datadir)/doc/$(PACKAGE)-$(VERSION)/html
-
-doc_files = $(DOXYGEN_OUT_FILES)
-
-EXTRA_DIST= $(doc_files)
-
-install:
- @$(NORMAL_INSTALL)
- if test "x$(DO_DOXYGEN)" = "xyes" ; then \
- $(mkinstalldirs) $(DESTDIR)$(doc_to); \
- for p in $(doc_files); do \
- $(INSTALL_DATA) $$p $(DESTDIR)$(doc_to)/$$p; \
- done; \
- fi
-
-uninstall:
- @$(NORMAL_UNINSTALL)
- if test "x$(DO_DOXYGEN)" = "xyes" ; then \
- for p in $(doc_files); do \
- rm -f $(DESTDIR)$(doc_to)/$$p; \
- done \
- fi
-
-MAINTAINERCLEANFILES = $(DOXYGEN_OUT_FILES)
-
diff --git a/doc/reference/.cvsignore b/doc/reference/.cvsignore
new file mode 100644
index 0000000..10c9dba
--- /dev/null
+++ b/doc/reference/.cvsignore
@@ -0,0 +1,11 @@
+*.txt
+html
+sgml
+tmpl
+xml
+.libs
+*.sgml
+Makefile
+Makefile.in
+libxklavier.*
+*.stamp
diff --git a/doc/reference/Makefile.am b/doc/reference/Makefile.am
new file mode 100644
index 0000000..532876b
--- /dev/null
+++ b/doc/reference/Makefile.am
@@ -0,0 +1,78 @@
+## Process this file with automake to produce Makefile.in
+
+# We require automake 1.6 at least.
+AUTOMAKE_OPTIONS = 1.6
+
+# This is a blank Makefile.am for using gtk-doc.
+# Copy this to your project's API docs directory and modify the variables to
+# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
+# of using the various options.
+
+# The name of the module, e.g. 'glib'.
+DOC_MODULE=libxklavier
+
+# The top-level SGML file. You can change this if you want to.
+DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
+
+# The directory containing the source code. Relative to $(srcdir).
+# gtk-doc will search all .c & .h files beneath here for inline comments
+# documenting the functions and macros.
+# e.g. DOC_SOURCE_DIR=../../../gtk
+DOC_SOURCE_DIR=../../libxklavier
+
+# Extra options to pass to gtkdoc-scangobj. Not normally needed.
+SCANGOBJ_OPTIONS=
+
+# Extra options to supply to gtkdoc-scan.
+# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
+SCAN_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkdb.
+# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
+MKDB_OPTIONS=--sgml-mode --output-format=xml
+
+# Extra options to supply to gtkdoc-mktmpl
+# e.g. MKTMPL_OPTIONS=--only-section-tmpl
+MKTMPL_OPTIONS=
+
+# Extra options to supply to gtkdoc-fixref. Not normally needed.
+# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
+FIXXREF_OPTIONS=
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
+# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
+HFILE_GLOB=
+CFILE_GLOB=
+
+# Header files to ignore when scanning.
+# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
+IGNORE_HFILES=xklavier_private.h xklavier_private_xkb.h xklavier_private_xmm.h xkl_engine_marshal.h
+
+# Images to copy into HTML directory.
+# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
+HTML_IMAGES=
+
+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
+# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
+content_files=
+
+# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
+# These files must be listed here *and* in content_files
+# e.g. expand_content_files=running.sgml
+expand_content_files=
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+# Only needed if you are using gtkdoc-scangobj to dynamically query widget
+# signals and properties.
+# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
+# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
+INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GLIB_CFLAGS)
+GTKDOC_LIBS=$(GLIB_LIBS) -L$(top_builddir)/libxklavier -lxklavier
+
+# This includes the standard gtk-doc make rules, copied by gtkdocize.
+include $(top_srcdir)/gtk-doc.make
+
+# Other files to distribute
+# e.g. EXTRA_DIST += version.xml.in
+EXTRA_DIST +=
diff --git a/libxklavier.spec.in b/libxklavier.spec.in
index 547b9dc..0076364 100644
--- a/libxklavier.spec.in
+++ b/libxklavier.spec.in
@@ -5,7 +5,7 @@ Release: 1
License: LGPL
Group: Development/Libraries
Url: http://gswitchit.sourceforge.net/
-BuildRequires: doxygen
+BuildRequires: gtk-doc
Source: http://gswitchit.sourceforge.net/%{name}-%{version}.tar.gz
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root
@@ -27,8 +27,7 @@ Libraries, include files, etc you can use to develop libxklavier applications.
%build
CONFIG_FLAGS="--prefix=%{_prefix} --libdir=%{_libdir} \
- --includedir=%{_includedir} --bindir=%{_bindir} \
- --disable-doxygen"
+ --includedir=%{_includedir} --bindir=%{_bindir}"
if [ ! -f configure ]; then
CFLAGS="$RPM_OPT_FLAGS" ./autogen.sh $CONFIG_FLAGS
@@ -65,7 +64,8 @@ rm -rf $RPM_BUILD_DIR/%{name}-%{version}
%files devel
%defattr(-, root, root)
-%doc doc/html/*.html doc/html/*.png doc/html/*.css
%{_libdir}/pkgconfig/*.pc
%{_libdir}/*a
%{_includedir}/*
+%{_datadir}/gtk-doc/html/libxklavier
+
diff --git a/libxklavier/.indent.pro b/libxklavier/.indent.pro
new file mode 100644
index 0000000..dbec33f
--- /dev/null
+++ b/libxklavier/.indent.pro
@@ -0,0 +1,3 @@
+-kr
+-i8
+-psl
diff --git a/libxklavier/Makefile.am b/libxklavier/Makefile.am
index 1643522..3eea793 100644
--- a/libxklavier/Makefile.am
+++ b/libxklavier/Makefile.am
@@ -14,8 +14,19 @@ else
ENABLE_XMM_SUPPORT_CFLAG = -DDISABLE_XMM_SUPPORT=1
endif
+EXTRA_DIST=marshal.list
+
+GLIB_GENMARSHAL = $(shell pkg-config --variable=glib_genmarshal glib-2.0)
+
+xkl_engine_marshal.h: marshal.list
+ $(GLIB_GENMARSHAL) --prefix=xkl_engine marshal.list --header > xkl_engine_marshal.h
+
+xkl_engine_marshal.c: xkl_engine_marshal.h
+ $(GLIB_GENMARSHAL) --prefix=xkl_engine marshal.list --body > xkl_engine_marshal.c
+
AM_CFLAGS=-Wall -Werror -DDATA_DIR=\"$(datadir)/$(PACKAGE)\" \
- -I. -I$(includedir) $(XML_CFLAGS) -I$(x_includes) -I$(top_srcdir) \
+ -I. -I$(includedir) -I$(x_includes) -I$(top_srcdir) \
+ $(XML_CFLAGS) $(GLIB_CFLAGS) \
$(XKB_HEADERS_PRESENT_CFLAG) \
$(ENABLE_XKB_SUPPORT_CFLAG) \
$(ENABLE_XMM_SUPPORT_CFLAG)
@@ -24,13 +35,16 @@ lib_LTLIBRARIES = libxklavier.la
noinst_HEADERS = xklavier_private.h xklavier_private_xkb.h xklavier_private_xmm.h
xklavierincdir = $(includedir)/libxklavier
-xklavierinc_HEADERS = xklavier.h xklavier_config.h
+xklavierinc_HEADERS = xklavier.h xkl_config_registry.h xkl_engine.h \
+ xkl_config_rec.h xkl_config_item.h xkl_engine_marshal.h
libxklavier_la_SOURCES = xklavier.c xklavier_evt.c xklavier_config.c \
- xklavier_xkb.c xklavier_evt_xkb.c xklavier_config_xkb.c \
+ xklavier_xkb.c xklavier_evt_xkb.c xklavier_config_xkb.c xklavier_toplevel.c \
xklavier_xmm.c xklavier_xmm_opts.c xklavier_evt_xmm.c xklavier_config_xmm.c \
- xklavier_util.c xklavier_config_i18n.c xklavier_props.c xklavier_dump.c \
+ xklavier_util.c xklavier_config_i18n.c xklavier_props.c xklavier_dump.c xkl_engine_marshal.c \
$(noinst_HEADERS) $(xklavierinc_HEADERS)
-libxklavier_la_LDFLAGS = -version-info @VERSION_INFO@ $(XML_LIBS) -lxkbfile -L$(x_libraries) $(LIBICONV)
+libxklavier_la_LDFLAGS = -version-info @VERSION_INFO@ \
+ $(XML_LIBS) $(GLIB_LIBS) \
+ -lxkbfile -L$(x_libraries) $(LIBICONV)
diff --git a/libxklavier/marshal.list b/libxklavier/marshal.list
new file mode 100644
index 0000000..3fcda01
--- /dev/null
+++ b/libxklavier/marshal.list
@@ -0,0 +1,3 @@
+VOID:VOID
+INT:LONG,LONG
+VOID:FLAGS,INT,BOOLEAN
diff --git a/libxklavier/xkl_config_item.h b/libxklavier/xkl_config_item.h
new file mode 100644
index 0000000..bad205a
--- /dev/null
+++ b/libxklavier/xkl_config_item.h
@@ -0,0 +1,116 @@
+#ifndef __XKL_CONFIG_ITEM_H__
+#define __XKL_CONFIG_ITEM_H__
+
+#include <glib-object.h>
+
+/*
+ * Maximum name length, including '\'0' character
+ */
+#define XKL_MAX_CI_NAME_LENGTH 32
+
+/*
+ * Maximum short description length, including '\\0' character
+ * (this length is in bytes, so for UTF-8 encoding in
+ * XML file the actual maximum length can be smaller)
+ */
+#define XKL_MAX_CI_SHORT_DESC_LENGTH 10
+
+/*
+ * Maximum description length, including '\\0' character
+ * (this length is in bytes, so for UTF-8 encoding in
+ * XML file the actual maximum length can be smaller)
+ */
+#define XKL_MAX_CI_DESC_LENGTH 192
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ typedef struct _XklConfigItem XklConfigItem;
+ typedef struct _XklConfigItemClass XklConfigItemClass;
+
+#define XKL_TYPE_CONFIG_ITEM (xkl_config_item_get_type ())
+#define XKL_CONFIG_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XKL_TYPE_CONFIG_ITEM, XklConfigItem))
+#define XKL_CONFIG_ITEM_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), XKL_CONFIG_ITEM, XklConfigItemClass))
+#define XKL_IS_CONFIG_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XKL_TYPE_CONFIG_ITEM))
+#define XKL_IS_CONFIG_ITEM_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), XKL_TYPE_CONFIG_ITEM))
+#define XKL_CONFIG_ITEM_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS ((obj), XKL_TYPE_CONFIG_ITEM, XklConfigItemClass))
+
+/**
+ * The configuration item. Corresponds to XML element "configItem".
+ */
+ struct _XklConfigItem {
+/**
+ * The superclass object
+ */
+ GObject parent;
+/**
+ * The configuration item name. Corresponds to XML element "name".
+ */
+ gchar name[XKL_MAX_CI_NAME_LENGTH];
+
+/**
+ * The configuration item short description. Corresponds to XML element "shortDescription".
+ */
+ gchar short_description[XKL_MAX_CI_DESC_LENGTH];
+
+/**
+ * The configuration item description. Corresponds to XML element "description".
+ */
+ gchar description[XKL_MAX_CI_DESC_LENGTH];
+ };
+
+/**
+ * The XklConfigItem class, derived from GObject
+ */
+ struct _XklConfigItemClass {
+ /**
+ * The superclass
+ */
+ GObjectClass parent_class;
+ };
+/**
+ * xkl_config_item_get_type:
+ *
+ * Get type info for XklConfigItem
+ *
+ * Returns: GType for XklConfigItem
+ */
+ extern GType xkl_config_item_get_type(void);
+
+/**
+ * xkl_config_item_new:
+ *
+ * Create new XklConfigItem
+ *
+ * Returns: new instance
+ */
+ extern XklConfigItem *xkl_config_item_new(void);
+
+/**
+ * ConfigItemProcessFunc:
+ * @item: the item from registry
+ * @data: anything which can be stored into the pointer
+ *
+ * Callback type used for enumerating keyboard models, layouts, variants, options
+ */
+ typedef void (*ConfigItemProcessFunc) (const XklConfigItem * item,
+ gpointer data);
+
+/**
+ * GroupProcessFunc:
+ * @item: the item from registry
+ * @allow_multiple_selection: a flag whether this group allows multiple selection
+ * @data: anything which can be stored into the pointer
+ *
+ * Callback type used for enumerating keyboard option groups
+ */
+ typedef void (*GroupProcessFunc) (const XklConfigItem * item,
+ gboolean
+ allow_multiple_selection,
+ gpointer data);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
diff --git a/libxklavier/xkl_config_rec.h b/libxklavier/xkl_config_rec.h
new file mode 100644
index 0000000..3170244
--- /dev/null
+++ b/libxklavier/xkl_config_rec.h
@@ -0,0 +1,220 @@
+#ifndef __XKL_CONFIG_REC_H__
+#define __XKL_CONFIG_REC_H__
+
+#include <glib-object.h>
+#include <libxklavier/xkl_engine.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ typedef struct _XklConfigRec XklConfigRec;
+ typedef struct _XklConfigRecClass XklConfigRecClass;
+
+#define XKL_TYPE_CONFIG_REC (xkl_config_rec_get_type ())
+#define XKL_CONFIG_REC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XKL_TYPE_CONFIG_REC, XklConfigRec))
+#define XKL_CONFIG_REC_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), XKL_CONFIG_REC, XklConfigRecClass))
+#define XKL_IS_CONFIG_REC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XKL_TYPE_CONFIG_REC))
+#define XKL_IS_CONFIG_REC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), XKL_TYPE_CONFIG_REC))
+#define XKL_CONFIG_REC_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS ((obj), XKL_TYPE_CONFIG_REC, XklConfigRecClass))
+
+/*
+ * Basic configuration params
+ */
+ struct _XklConfigRec {
+/*
+ * The superclass object
+ */
+ GObject parent;
+/*
+ * The keyboard model
+ */
+ gchar *model;
+/*
+ * The array of keyboard layouts
+ */
+ gchar **layouts;
+/*
+ * The array of keyboard layout variants (if any)
+ */
+ gchar **variants;
+/*
+ * The array of keyboard layout options
+ */
+ gchar **options;
+ };
+
+/*
+ * The XklConfigRec class, derived from GObject
+ */
+ struct _XklConfigRecClass {
+ /*
+ * The superclass
+ */
+ GObjectClass parent_class;
+ };
+
+/**
+ * xkl_config_rec_get_type:
+ *
+ * Get type info for XConfigRec
+ *
+ * Returns: GType for XConfigRec
+ */
+ extern GType xkl_config_rec_get_type(void);
+
+/**
+ * xkl_config_rec_new:
+ *
+ * Create new XklConfigRec
+ *
+ * Returns: new instance
+ */
+ extern XklConfigRec *xkl_config_rec_new(void);
+
+/**
+ * xkl_config_rec_activate:
+ * @data: valid XKB configuration
+ * @engine: the engine
+ *
+ * Activates some XKB configuration
+ * description. Can be NULL
+ *
+ * Returns: TRUE on success
+ */
+ extern gboolean xkl_config_rec_activate(const XklConfigRec * data,
+ XklEngine * engine);
+
+/**
+ * xkl_config_rec_get_from_server:
+ * @data: buffer for XKB configuration
+ * @engine: the engine
+ *
+ * Loads the current XKB configuration (from X server)
+ *
+ * Returns: TRUE on success
+ */
+ extern gboolean xkl_config_rec_get_from_server(XklConfigRec * data,
+ XklEngine * engine);
+
+/**
+ * xkl_config_rec_get_from_backup:
+ * @data: buffer for XKB configuration
+ * @engine: the engine
+ *
+ * Loads the current XKB configuration (from backup)
+ *
+ * Returns: TRUE on success
+ */
+ extern gboolean xkl_config_rec_get_from_backup(XklConfigRec * data,
+ XklEngine * engine);
+
+/**
+ * xkl_config_rec_write_to_file:
+ * @file_name: name of the file to create
+ * @data: valid XKB configuration
+ * description. Can be NULL
+ * @binary: flag indicating whether the output file should be binary
+ * @engine: the engine
+ *
+ * Writes some XKB configuration into XKM/XKB/... file
+ *
+ * Returns: TRUE on success
+ */
+ extern gboolean xkl_config_rec_write_to_file(XklEngine * engine,
+ const gchar *
+ file_name,
+ const XklConfigRec *
+ data,
+ const gboolean
+ binary);
+
+/**
+ * xkl_config_rec_get_from_root_window_property:
+ * @rules_atom_name: atom name of the root window property to read
+ * @rules_file_out: pointer to hold the file name
+ * @config_out: buffer to hold the result
+ * @engine: the engine
+ *
+ * Gets the XKB configuration from any root window property
+ *
+ * Returns: TRUE on success
+ */
+ extern gboolean
+ xkl_config_rec_get_from_root_window_property(XklConfigRec *
+ config_out,
+ Atom
+ rules_atom_name,
+ gchar **
+ rules_file_out,
+ XklEngine *
+ engine);
+
+/**
+ * xkl_config_rec_set_to_root_window_property:
+ * @rules_atom_name: atom name of the root window property to write
+ * @rules_file: rules file name
+ * @config: configuration to save
+ * @engine: the engine
+ *
+ * Saves the XKB configuration into any root window property
+ *
+ * Returns: TRUE on success
+ */
+ extern gboolean xkl_config_rec_set_to_root_window_property(const
+ XklConfigRec
+ *
+ config,
+ Atom
+ rules_atom_name,
+ gchar *
+ rules_file,
+ XklEngine
+ *
+ engine);
+
+/**
+ * xkl_backup_names_prop:
+ * @engine: the engine
+ *
+ * Backups current XKB configuration into some property -
+ * if this property is not defined yet.
+ *
+ * Returns: TRUE on success
+ */
+ extern gboolean xkl_backup_names_prop(XklEngine * engine);
+
+/**
+ * xkl_restore_names_prop:
+ * @engine: the engine
+ *
+ * Restores XKB from the property saved by xkl_backup_names_prop
+ *
+ * Returns: TRUE on success
+ */
+ extern gboolean xkl_restore_names_prop(XklEngine * engine);
+
+/**
+ * xkl_config_rec_reset:
+ * @data: record to reset
+ *
+ * Resets the record (equal to Destroy and Init)
+ */
+ extern void xkl_config_rec_reset(XklConfigRec * data);
+
+/**
+ * xkl_config_rec_equals:
+ * @data1: record to compare
+ * @data2: another record
+ *
+ * Compares two records
+ *
+ * Returns: TRUE if records are same
+ */
+ extern gboolean xkl_config_rec_equals(XklConfigRec * data1,
+ XklConfigRec * data2);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
diff --git a/libxklavier/xkl_config_registry.h b/libxklavier/xkl_config_registry.h
new file mode 100644
index 0000000..a1c108e
--- /dev/null
+++ b/libxklavier/xkl_config_registry.h
@@ -0,0 +1,264 @@
+#ifndef __XKL_CONFIG_REGISTRY_H__
+#define __XKL_CONFIG_REGISTRY_H__
+
+#include <glib-object.h>
+#include <libxklavier/xkl_engine.h>
+#include <libxklavier/xkl_config_item.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+ typedef struct _XklConfigRegistry XklConfigRegistry;
+ typedef struct _XklConfigRegistryPrivate XklConfigRegistryPrivate;
+ typedef struct _XklConfigRegistryClass XklConfigRegistryClass;
+
+#define XKL_TYPE_CONFIG_REGISTRY (xkl_config_registry_get_type ())
+#define XKL_CONFIG_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XKL_TYPE_CONFIG_REGISTRY, XklConfigRegistry))
+#define XKL_CONFIG_REGISTRY_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), XKL_TYPE_CONFIG_REGISTRY, XklConfigRegistryClass))
+#define XKL_IS_CONFIG_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XKL_TYPE_CONFIG_REGISTRY))
+#define XKL_IS_CONFIG_REGISTRY_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), XKL_TYPE_CONFIG_REGISTRY))
+#define XKL_CONFIG_REGISTRY_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS ((obj), XKL_TYPE_CONFIG_REGISTRY, XklConfigRegistryClass))
+
+/**
+ * The configuration manager. Corresponds to XML element "configItem".
+ */
+ struct _XklConfigRegistry {
+/**
+ * The superclass object
+ */
+ GObject parent;
+
+ XklConfigRegistryPrivate *priv;
+ };
+
+/**
+ * The XklConfigRegistry class, derived from GObject
+ */
+ struct _XklConfigRegistryClass {
+ /**
+ * The superclass
+ */
+ GObjectClass parent_class;
+ };
+/**
+ * xkl_config_registry_get_type:
+ *
+ * Get type info for XConfig
+ *
+ * Returns: GType for XConfig
+ */
+ extern GType xkl_config_registry_get_type(void);
+
+/**
+ * xkl_config_registry_get_instance:
+ * @engine: the engine to use for accessing X in all the operations
+ * (like accessing root window properties etc)
+ *
+ * Create new XklConfig
+ *
+ * Returns: new instance
+ */
+ extern XklConfigRegistry
+ * xkl_config_registry_get_instance(XklEngine * engine);
+
+/**
+ * xkl_config_registry_load_from_file:
+ * @config: the config registry
+ * @file_name: file to load
+ *
+ * Loads XML configuration registry
+ *
+ * Returns: TRUE on success
+ */
+ extern gboolean
+ xkl_config_registry_load_from_file(XklConfigRegistry * config,
+ const gchar * file_name);
+
+/**
+ * xkl_config_registry_load:
+ * @config: the config registry
+ *
+ * Loads XML configuration registry. The name is taken from X server
+ * (for XKB/libxkbfile, from the root window property)
+ *
+ * Returns: TRUE on success
+ */
+ extern gboolean xkl_config_registry_load(XklConfigRegistry *
+ config);
+
+/**
+ * xkl_config_registry_free:
+ * @config: the config registry
+ *
+ * Frees XML configuration registry
+ */
+ extern void xkl_config_registry_free(XklConfigRegistry * config);
+
+/**
+ * xkl_config_registry_foreach_model:
+ * @config: the config registry
+ * @func: callback to call for every model
+ * @data: anything which can be stored into the pointer
+ *
+ * Enumerates keyboard models from the XML configuration registry
+ */
+ extern void xkl_config_registry_foreach_model(XklConfigRegistry *
+ config,
+ ConfigItemProcessFunc
+ func, gpointer data);
+
+/**
+ * xkl_config_registry_foreach_layout:
+ * @config: the config registry
+ * @func: callback to call for every layout
+ * @data: anything which can be stored into the pointer
+ *
+ * Enumerates keyboard layouts from the XML configuration registry
+ */
+ extern void xkl_config_registry_foreach_layout(XklConfigRegistry *
+ config,
+ ConfigItemProcessFunc
+ func,
+ gpointer data);
+
+/**
+ * xkl_config_registry_foreach_layout_variant:
+ * @config: the config registry
+ * @layout_name: layout name for which variants will be listed
+ * @func: callback to call for every layout variant
+ * @data: anything which can be stored into the pointer
+ *
+ * Enumerates keyboard layout variants from the XML configuration registry
+ */
+ extern void
+ xkl_config_registry_foreach_layout_variant(XklConfigRegistry *
+ config,
+ const gchar *
+ layout_name,
+ ConfigItemProcessFunc
+ func, gpointer data);
+
+/**
+ * xkl_config_registry_foreach_option_group:
+ * @config: the config registry
+ * @func: callback to call for every option group
+ * @data: anything which can be stored into the pointer
+ *
+ * Enumerates keyboard option groups from the XML configuration registry
+ */
+ extern void
+ xkl_config_registry_foreach_option_group(XklConfigRegistry *
+ config,
+ GroupProcessFunc func,
+ gpointer data);
+
+/**
+ * xkl_config_registry_foreach_option:
+ * @config: the config registry
+ * @option_group_name: option group name for which variants
+ * will be listed
+ * @func: callback to call for every option
+ * @data: anything which can be stored into the pointer
+ *
+ * Enumerates keyboard options from the XML configuration registry
+ */
+ extern void xkl_config_registry_foreach_option(XklConfigRegistry *
+ config,
+ const gchar *
+ option_group_name,
+ ConfigItemProcessFunc
+ func,
+ gpointer data);
+
+/**
+ * xkl_config_registry_find_model:
+ * @config: the config registry
+ * @item: pointer to a XklConfigItem containing the name of the
+ * keyboard model. On successfull return, the descriptions are filled.
+ *
+ * Loads a keyboard model information from the XML configuration registry.
+ *
+ * Returns: TRUE if appropriate element was found and loaded
+ */
+ extern gboolean xkl_config_registry_find_model(XklConfigRegistry *
+ config,
+ XklConfigItem *
+ item);
+
+/**
+ * xkl_config_registry_find_layout:
+ * @config: the config registry
+ * @item: pointer to a XklConfigItem containing the name of the
+ * keyboard layout. On successfull return, the descriptions are filled.
+ *
+ * Loads a keyboard layout information from the XML configuration registry.
+ *
+ * Returns: TRUE if appropriate element was found and loaded
+ */
+ extern gboolean xkl_config_registry_find_layout(XklConfigRegistry *
+ config,
+ XklConfigItem *
+ item);
+
+/**
+ * xkl_config_registry_find_variant:
+ * @config: the config registry
+ * @layout_name: name of the parent layout
+ * @item: pointer to a XklConfigItem containing the name of the
+ * keyboard layout variant. On successfull return, the descriptions are filled.
+ *
+ * Loads a keyboard layout variant information from the XML configuration
+ * registry.
+ *
+ * Returns: TRUE if appropriate element was found and loaded
+ */
+ extern gboolean xkl_config_registry_find_variant(XklConfigRegistry
+ * config,
+ const char
+ *layout_name,
+ XklConfigItem *
+ item);
+
+/**
+ * xkl_config_registry_find_option_group:
+ * @config: the config registry
+ * @item: pointer to a XklConfigItem containing the name of the
+ * keyboard option group. On successfull return, the descriptions are filled.
+ * @allow_multiple_selection: pointer to some gboolean variable to fill
+ * the corresponding attribute of XML element "group".
+ *
+ * Loads a keyboard option group information from the XML configuration
+ * registry.
+ *
+ * Returns: TRUE if appropriate element was found and loaded
+ */
+ extern gboolean
+ xkl_config_registry_find_option_group(XklConfigRegistry *
+ config,
+ XklConfigItem * item,
+ gboolean *
+ allow_multiple_selection);
+
+/**
+ * xkl_config_registry_find_option:
+ * @config: the config registry
+ * @option_group_name: name of the option group
+ * @item: pointer to a XklConfigItem containing the name of the
+ * keyboard option. On successfull return, the descriptions are filled.
+ *
+ * Loads a keyboard option information from the XML configuration
+ * registry.
+ *
+ * Returns: TRUE if appropriate element was found and loaded
+ */
+ extern gboolean xkl_config_registry_find_option(XklConfigRegistry *
+ config,
+ const gchar *
+ option_group_name,
+ XklConfigItem *
+ item);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
diff --git a/libxklavier/xkl_engine.h b/libxklavier/xkl_engine.h
new file mode 100644
index 0000000..4143059
--- /dev/null
+++ b/libxklavier/xkl_engine.h
@@ -0,0 +1,547 @@
+#ifndef __XKL_ENGINE_H__
+#define __XKL_ENGINE_H__
+
+#include <X11/Xlib.h>
+
+#include <glib-object.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ typedef struct _XklEngine XklEngine;
+ typedef struct _XklEnginePrivate XklEnginePrivate;
+ typedef struct _XklEngineClass XklEngineClass;
+
+#define XKL_TYPE_ENGINE (xkl_engine_get_type ())
+#define XKL_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XKL_TYPE_ENGINE, XklEngine))
+#define XKL_ENGINE_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), XKL_TYPE_ENGINE, XklEngineClass))
+#define XKL_IS_ENGINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XKL_TYPE_ENGINE))
+#define XKL_IS_ENGINE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((obj), XKL_TYPE_ENGINE))
+#define XKL_ENGINE_GET_CLASS (G_TYPE_INSTANCE_GET_CLASS ((obj), XKL_TYPE_ENGINE, XklEngineClass))
+
+/**
+ * The type of the keyboard state change
+ * GroupChanged: Group was changed
+ * IndicatorsChanged: Indicators were changed
+ */
+ typedef enum {
+ GROUP_CHANGED,
+ INDICATORS_CHANGED
+ } XklEngineStateChange;
+
+/**
+ * A set of flags used to indicate the capabilities of the active backend
+ * CanToggleIndicators: Backend allows to toggls indicators on/off
+ * CanOutputConfigAsASCII: Backend allows writing ASCII representation of the configuration
+ * CanOutputConfigAsBinary: Backend allows writing binary representation of the configuration
+ * MultipleLayoutsSupported: Backend supports multiple layouts
+ * RequiresManualLayoutManagement: Backend requires manual configuration, some daemon should do
+ * xkl_start_listen(engine,XKLL_MANAGE_LAYOUTS);
+ */
+ typedef enum {
+ XKLF_CAN_TOGGLE_INDICATORS = 0x01,
+ XKLF_CAN_OUTPUT_CONFIG_AS_ASCII = 0x02,
+ XKLF_CAN_OUTPUT_CONFIG_AS_BINARY = 0x04,
+ XKLF_MULTIPLE_LAYOUTS_SUPPORTED = 0x08,
+ XKLF_REQUIRES_MANUAL_LAYOUT_MANAGEMENT = 0x10,
+ } XklEngineFeatures;
+
+/**
+ * XKB state. Can be global or per-window
+ */
+ typedef struct {
+/**
+ * selected group
+ */
+ gint32 group;
+/**
+ * set of active indicators
+ */
+ guint32 indicators;
+ } XklState;
+
+/**
+ * The main Xklavier engine class
+ */
+ struct _XklEngine {
+/**
+ * The superclass object
+ */
+ GObject parent;
+/**
+ * Private data
+ */
+ XklEnginePrivate *priv;
+ };
+
+/**
+ * The XklEngine class, derived from GObject
+ */
+ struct _XklEngineClass {
+/**
+ * The superclass
+ */
+ GObjectClass parent_class;
+
+/**
+ * XklEngine::config-notify:
+ * @engine: the object on which the signal is emitted
+ *
+ * Used for notifying application of the XKB configuration change.
+ */
+ void (*config_notify) (XklEngine * engine);
+
+/**
+ * XklEngine::new_window_notify:
+ * @engine: the object on which the signal is emitted
+ * @win: new window
+ * @parent: new window's parent
+ *
+ * Used for notifying application of new window creation (actually,
+ * registration).
+ *
+ * Returns: the initial group id for the window (-1 to use the default value)
+ */
+ gint(*new_window_notify) (XklEngine * engine, Window win,
+ Window parent);
+/**
+ * XklEngine::state_notify
+ * @engine: the object on which the signal is emitted
+ * @change_type: mask of changes
+ * @group: new group
+ * @restore: whether this state is restored from
+ * saved state of set as new.
+ *
+ * Used for notifying application of the window state change.
+ */
+ void (*state_notify) (XklEngine * engine,
+ XklEngineStateChange change_type,
+ gint group, gboolean restore);
+
+ };
+
+
+/**
+ * xkl_engine_get_type:
+ *
+ * Get type info for XklEngine
+ *
+ * Returns: GType for XklEngine
+ */
+ extern GType xkl_engine_get_type(void);
+
+
+/**
+ * xkl_engine_get_instance:
+ * @display: the X display used by the application
+ *
+ * Get the instance of the XklEngine. Within a process, there is always once instance.
+ *
+ * Returns: the singleton instance
+ */
+ extern XklEngine *xkl_engine_get_instance(Display * display);
+
+
+/**
+ * xkl_engine_get_backend_name:
+ * @engine: the engine
+ *
+ * What kind of backend is used
+ *
+ * Returns: some string id of the backend
+ */
+ extern const gchar *xkl_engine_get_backend_name(XklEngine *
+ engine);
+
+/**
+ * xkl_engine_get_features:
+ * @engine: the engine
+ *
+ * Provides information regarding available backend features
+ * (combination of XKLF_* constants)
+ *
+ * Returns: ORed XKLF_* constants
+ */
+ extern guint xkl_engine_get_features(XklEngine * engine);
+
+/**
+ * xkl_engine_get_max_num_groups:
+ * @engine: the engine
+ *
+ * Provides the information on maximum number of simultaneously supported
+ * groups (layouts)
+ *
+ * Returns: maximum number of the groups in configuration,
+ * 0 if no restrictions.
+ */
+ extern guint xkl_engine_get_max_num_groups(XklEngine * engine);
+
+/**
+ * The listener action modes:
+ * ManageWindowStates: The listener process should handle the per-window states
+ * and all the related activity
+ * TrackKeyboardState: Just track the state and pass it to the application above.
+ * ManageLayouts: The listener process should help backend to maintain the configuration
+ * (manually switch layouts etc).
+ */
+ typedef enum {
+ XKLL_MANAGE_WINDOW_STATES = 0x01,
+ XKLL_TRACK_KEYBOARD_STATE = 0x02,
+ XKLL_MANAGE_LAYOUTS = 0x04
+ } XklEngineListenModes;
+
+/**
+ * xkl_engine_start_listen:
+ * @engine: the engine
+ * @flags: any combination of XKLL_* constants
+ *
+ * Starts listening for XKB-related events
+ *
+ * Returns: 0
+ */
+ extern gint xkl_engine_start_listen(XklEngine * engine,
+ guint flags);
+
+/**
+ * xkl_engine_stop_listen:
+ * @engine: the engine
+ *
+ * Stops listening for XKB-related events
+ * Returns: 0
+ */
+ extern gint xkl_engine_stop_listen(XklEngine * engine);
+
+/**
+ * xkl_engine_pause_listen:
+ * @engine: the engine
+ *
+ * Temporary pauses listening for XKB-related events
+ *
+ * Returns: 0
+ */
+ extern gint xkl_engine_pause_listen(XklEngine * engine);
+
+/**
+ * xkl_engine_resume_listen:
+ * @engine: the engine
+ *
+ * Resumes listening for XKB-related events
+ *
+ * Returns: 0
+ */
+ extern gint xkl_engine_resume_listen(XklEngine * engine);
+
+/**
+ * xkl_engine_grab_key:
+ * @engine: the engine
+ * @keycode: keycode
+ * @modifiers: bitmask of modifiers
+ *
+ * Grabs some key
+ *
+ * Returns: TRUE on success
+ */
+ extern gboolean xkl_engine_grab_key(XklEngine * engine,
+ gint keycode, guint modifiers);
+
+/**
+ * xkl_engine_ungrab_key:
+ * @engine: the engine
+ * @keycode: keycode
+ * @modifiers: bitmask of modifiers
+ *
+ * Ungrabs some key
+ *
+ * Returns: TRUE on success
+ */
+ extern gboolean xkl_engine_ungrab_key(XklEngine * engine,
+ gint keycode,
+ guint modifiers);
+
+/**
+ * xkl_engine_filter_events:
+ * @engine: the engine
+ * @evt: delivered X event
+ *
+ * Processes X events. Should be included into the main event cycle of an
+ * application. One of the most important functions.
+ *
+ * Returns: 0 if the event it processed - 1 otherwise
+ */
+ extern gint xkl_engine_filter_events(XklEngine * engine,
+ XEvent * evt);
+
+/**
+ * xkl_engine_allow_one_switch_to_secondary_group:
+ * @engine: the engine
+ *
+ * Allows to switch (once) to the secondary group
+ *
+ */
+ extern void
+ xkl_engine_allow_one_switch_to_secondary_group(XklEngine *
+ engine);
+
+/**
+ * xkl_engine_get_current_window:
+ * @engine: the engine
+ *
+ * Returns: currently focused window
+ */
+ extern Window xkl_engine_get_current_window(XklEngine * engine);
+
+/**
+ * xkl_engine_get_current_state:
+ * @engine: the engine
+ *
+ * Returns: current state of the keyboard.
+ * Returned value is a statically allocated buffer, should not be freed.
+ */
+ extern XklState *xkl_engine_get_current_state(XklEngine * engine);
+
+/**
+ * xkl_engine_get_window_title:
+ * @engine: the engine
+ * @win: X window
+ *
+ * Returns: the window title of some window or NULL.
+ * If not NULL, it should be freed with XFree
+ */
+ extern gchar *xkl_engine_get_window_title(XklEngine * engine,
+ Window win);
+
+/**
+ * xkl_engine_get_state:
+ * @engine: the engine
+ * @win: window to query
+ * @state_out: structure to store the state
+ *
+ * Finds the state for a given window (for its "App window").
+ *
+ * Returns: TRUE on success, otherwise FALSE
+ * (the error message can be obtained using xkl_GetLastError).
+ */
+ extern gboolean xkl_engine_get_state(XklEngine * engine,
+ Window win,
+ XklState * state_out);
+
+/**
+ * xkl_engine_delete_state:
+ * @engine: the engine
+ * @win: target window
+ *
+ * Drops the state of a given window (of its "App window").
+ */
+ extern void xkl_engine_delete_state(XklEngine * engine,
+ Window win);
+
+/**
+ * xkl_engine_save_state:
+ * @engine: the engine
+ * @win: target window
+ * @state: new state of the window
+ *
+ * Stores ths state for a given window
+ */
+ extern void xkl_engine_save_state(XklEngine * engine, Window win,
+ XklState * state);
+
+/**
+ * xkl_engine_set_window_transparent:
+ * @engine: the engine
+ * @win: window do set the flag for.
+ * @transparent: if true, the windows is transparent.
+ *
+ * Sets the "transparent" flag. It means focus switching onto
+ * this window will never change the state.
+ */
+ extern void xkl_engine_set_window_transparent(XklEngine * engine,
+ Window win,
+ gboolean
+ transparent);
+
+/**
+ * xkl_engine_is_window_transparent:
+ * @engine: the engine
+ * @win: window to get the transparent flag from.
+ *
+ * Returns: TRUE if the window is "transparent"
+ */
+ extern gboolean xkl_engine_is_window_transparent(XklEngine *
+ engine,
+ Window win);
+
+/**
+ * xkl_engine_is_window_from_same_toplevel_window:
+ * @engine: the engine
+ * @win1: first window
+ * @win2: second window
+ *
+ * Checks whether 2 windows have the same topmost window
+ *
+ * Returns: TRUE is windows are in the same application
+ */
+ extern gboolean
+ xkl_engine_is_window_from_same_toplevel_window(XklEngine *
+ engine,
+ Window win1,
+ Window win2);
+
+/**
+ * xkl_engine_get_num_groups:
+ * @engine: the engine
+ *
+ * Returns: the total number of groups in the current configuration
+ * (keyboard)
+ */
+ extern guint xkl_engine_get_num_groups(XklEngine * engine);
+
+/**
+ * xkl_engine_get_groups_names:
+ * @engine: the engine
+ *
+ * Returns: the array of group names for the current XKB configuration
+ * (keyboard).
+ * This array is static, should not be freed
+ */
+ extern const gchar **xkl_engine_get_groups_names(XklEngine *
+ engine);
+
+/**
+ * xkl_engine_get_indicators_names:
+ * @engine: the engine
+ *
+ * Returns: the array of indicator names for the current XKB configuration
+ * (keyboard).
+ * This array is static, should not be freed
+ */
+ extern const gchar **xkl_engine_get_indicators_names(XklEngine *
+ engine);
+
+/**
+ * xkl_engine_get_next_group:
+ * @engine: the engine
+ *
+ * Calculates next group id. Does not change the state of anything.
+ *
+ * Returns: next group id
+ */
+ extern gint xkl_engine_get_next_group(XklEngine * engine);
+
+/**
+ * xkl_engine_get_prev_group:
+ * @engine: the engine
+ *
+ * Calculates prev group id. Does not change the state of anything.
+ *
+ * Returns: prev group id
+ */
+ extern gint xkl_engine_get_prev_group(XklEngine * engine);
+
+/**
+ * xkl_engine_get_current_window_group:
+ * @engine: the engine
+ *
+ * Returns: saved group id of the current window.
+ */
+ extern gint xkl_engine_get_current_window_group(XklEngine *
+ engine);
+
+/**
+ * xkl_engine_lock_group:
+ * @engine: the engine
+ * @group: group number for locking
+ *
+ * Locks the group. Can be used after xkl_GetXXXGroup functions
+ */
+ extern void xkl_engine_lock_group(XklEngine * engine, gint group);
+
+/**
+ * xkl_engine_set_group_per_toplevel_window:
+ * @engine: the engine
+ * @is_global: new parameter value
+ *
+ * Sets the configuration parameter: group per application
+ */
+ extern void xkl_engine_set_group_per_toplevel_window(XklEngine *
+ engine,
+ gboolean
+ is_global);
+
+/**
+ * xkl_engine_is_group_per_toplevel_window:
+ * @engine: the engine
+ *
+ * Returns: the value of the parameter: group per application
+ */
+ extern gboolean xkl_engine_is_group_per_toplevel_window(XklEngine *
+ engine);
+
+/**
+ * xkl_engine_set_indicators_handling:
+ * @engine: the engine
+ * @whether_handle: new parameter value
+ *
+ * Sets the configuration parameter: perform indicators handling
+ */
+ extern void xkl_engine_set_indicators_handling(XklEngine * engine,
+ gboolean
+ whether_handle);
+
+/**
+ * xkl_engine_get_indicators_handling:
+ * @engine: the engine
+ *
+ * Returns: the value of the parameter: perform indicator handling
+ */
+ extern gboolean xkl_engine_get_indicators_handling(XklEngine *
+ engine);
+
+/**
+ * xkl_engine_set_secondary_groups_mask:
+ * @engine: the engine
+ * @mask: new group mask
+ *
+ * Sets the secondary groups (one bit per group).
+ * Secondary groups require explicit "allowance" for switching
+ */
+ extern void xkl_engine_set_secondary_groups_mask(XklEngine *
+ engine,
+ guint mask);
+
+/**
+ * xkl_engine_get_secondary_groups_mask:
+ * @engine: the engine
+ *
+ * Returns: the secondary group mask
+ */
+ extern guint xkl_engine_get_secondary_groups_mask(XklEngine *
+ engine);
+
+/**
+ * xkl_engine_group_set_default:
+ * @engine: the engine
+ * @group: default group
+ *
+ * Configures the default group set on window creation.
+ * If -1, no default group is used
+ */
+ extern void xkl_engine_group_set_default(XklEngine * engine,
+ gint group);
+
+/**
+ * xkl_engine_group_get_default:
+ * @engine: the engine
+ *
+ * Returns the default group set on window creation
+ * If -1, no default group is used
+ *
+ * Returns: the default group
+ */
+ extern gint xkl_engine_group_get_default(XklEngine * engine);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
diff --git a/libxklavier/xkl_engine_marshal.c b/libxklavier/xkl_engine_marshal.c
new file mode 100644
index 0000000..ac10620
--- /dev/null
+++ b/libxklavier/xkl_engine_marshal.c
@@ -0,0 +1,131 @@
+
+#include <glib-object.h>
+
+
+#ifdef G_ENABLE_DEBUG
+#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
+#define g_marshal_value_peek_char(v) g_value_get_char (v)
+#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
+#define g_marshal_value_peek_int(v) g_value_get_int (v)
+#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
+#define g_marshal_value_peek_long(v) g_value_get_long (v)
+#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
+#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
+#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
+#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
+#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
+#define g_marshal_value_peek_float(v) g_value_get_float (v)
+#define g_marshal_value_peek_double(v) g_value_get_double (v)
+#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
+#define g_marshal_value_peek_param(v) g_value_get_param (v)
+#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
+#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
+#define g_marshal_value_peek_object(v) g_value_get_object (v)
+#else /* !G_ENABLE_DEBUG */
+/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
+ * Do not access GValues directly in your code. Instead, use the
+ * g_value_get_*() functions
+ */
+#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
+#define g_marshal_value_peek_char(v) (v)->data[0].v_int
+#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
+#define g_marshal_value_peek_int(v) (v)->data[0].v_int
+#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
+#define g_marshal_value_peek_long(v) (v)->data[0].v_long
+#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
+#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
+#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
+#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
+#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
+#define g_marshal_value_peek_float(v) (v)->data[0].v_float
+#define g_marshal_value_peek_double(v) (v)->data[0].v_double
+#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
+#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
+#endif /* !G_ENABLE_DEBUG */
+
+
+/* VOID:VOID (marshal.list:1) */
+
+/* INT:LONG,LONG (marshal.list:2) */
+void
+xkl_engine_INT__LONG_LONG (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ typedef gint (*GMarshalFunc_INT__LONG_LONG) (gpointer data1,
+ glong arg_1,
+ glong arg_2,
+ gpointer data2);
+ register GMarshalFunc_INT__LONG_LONG callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gint v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 3);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_INT__LONG_LONG) (marshal_data ? marshal_data : cc->callback);
+
+ v_return = callback (data1,
+ g_marshal_value_peek_long (param_values + 1),
+ g_marshal_value_peek_long (param_values + 2),
+ data2);
+
+ g_value_set_int (return_value, v_return);
+}
+
+/* VOID:FLAGS,INT,BOOLEAN (marshal.list:3) */
+void
+xkl_engine_VOID__FLAGS_INT_BOOLEAN (GClosure *closure,
+ GValue *return_value,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ typedef void (*GMarshalFunc_VOID__FLAGS_INT_BOOLEAN) (gpointer data1,
+ guint arg_1,
+ gint arg_2,
+ gboolean arg_3,
+ gpointer data2);
+ register GMarshalFunc_VOID__FLAGS_INT_BOOLEAN callback;
+ register GCClosure *cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+
+ g_return_if_fail (n_param_values == 4);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_VOID__FLAGS_INT_BOOLEAN) (marshal_data ? marshal_data : cc->callback);
+
+ callback (data1,
+ g_marshal_value_peek_flags (param_values + 1),
+ g_marshal_value_peek_int (param_values + 2),
+ g_marshal_value_peek_boolean (param_values + 3),
+ data2);
+}
+
diff --git a/libxklavier/xkl_engine_marshal.h b/libxklavier/xkl_engine_marshal.h
new file mode 100644
index 0000000..c1e4115
--- /dev/null
+++ b/libxklavier/xkl_engine_marshal.h
@@ -0,0 +1,27 @@
+
+#ifndef __xkl_engine_MARSHAL_H__
+#define __xkl_engine_MARSHAL_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+/* VOID:VOID (marshal.list:1) */
+#define xkl_engine_VOID__VOID g_cclosure_marshal_VOID__VOID
+/* INT:LONG,LONG (marshal.list:2) */
+extern void xkl_engine_INT__LONG_LONG(GClosure * closure,
+ GValue * return_value,
+ guint n_param_values,
+ const GValue * param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+/* VOID:FLAGS,INT,BOOLEAN (marshal.list:3) */
+extern void xkl_engine_VOID__FLAGS_INT_BOOLEAN(GClosure * closure,
+ GValue * return_value,
+ guint n_param_values,
+ const GValue * param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data);
+
+G_END_DECLS
+#endif /* __xkl_engine_MARSHAL_H__ */
diff --git a/libxklavier/xklavier.c b/libxklavier/xklavier.c
index a820f50..d20c873 100644
--- a/libxklavier/xklavier.c
+++ b/libxklavier/xklavier.c
@@ -1,860 +1,880 @@
+#include <string.h>
#include <time.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <X11/Xlibint.h>
+#include <X11/Xmd.h>
#include "xklavier_private.h"
+#include "xkl_engine_marshal.h"
-Display *_xklDpy;
+static GObjectClass *parent_class = NULL;
-XklState _xklCurState;
+static XklEngine *the_engine = NULL;
-Window _xklCurClient;
+gint xkl_debug_level = 0;
-Status _xklLastErrorCode;
+static XklLogAppender log_appender = xkl_default_log_appender;
-const char *_xklLastErrorMsg;
+const gchar *xkl_last_error_message;
-XErrorHandler _xklDefaultErrHandler;
+enum {
+ PROP_0,
+ PROP_DISPLAY,
+ PROP_BACKEND_NAME,
+ PROP_FEATURES,
+ PROP_MAX_NUM_GROUPS,
+ PROP_NUM_GROUPS,
+ PROP_DEFAULT_GROUP,
+ PROP_SECONDARY_GROUPS_MASK,
+ PROP_INDICATORS_HANDLING,
+};
-Atom _xklAtoms[TOTAL_ATOMS];
-
-Window _xklRootWindow;
-
-int _xklDefaultGroup;
-
-Bool _xklSkipOneRestore;
-
-int _xklSecondaryGroupsMask;
-
-int _xklDebugLevel = 0;
-
-Window _xklPrevAppWindow;
-
-int _xklListenerType = 0;
-
-XklVTable *xklVTable = NULL;
-
-XklConfigCallback _xklConfigCallback = NULL;
-void *_xklConfigCallbackData;
-
-static XklStateCallback stateCallback = NULL;
-static void *stateCallbackData;
-
-static XklWinCallback winCallback = NULL;
-static void *winCallbackData;
-
-static XklLogAppender logAppender = XklDefaultLogAppender;
-
-static Bool groupPerApp = True;
-
-static Bool handleIndicators = False;
-
-
-void XklSetIndicatorsHandling( Bool whetherHandle )
+void
+xkl_engine_set_indicators_handling(XklEngine * engine,
+ gboolean whether_handle)
{
- handleIndicators = whetherHandle;
+ xkl_engine_priv(engine, handle_indicators) = whether_handle;
}
-Bool XklGetIndicatorsHandling( void )
+gboolean
+xkl_engine_get_indicators_handling(XklEngine * engine)
{
- return handleIndicators;
+ return xkl_engine_priv(engine, handle_indicators);
}
-void XklSetDebugLevel( int level )
+void
+xkl_set_debug_level(int level)
{
- _xklDebugLevel = level;
+ xkl_debug_level = level;
}
-void XklSetGroupPerApp( Bool isSet )
+void
+xkl_engine_set_group_per_toplevel_window(XklEngine * engine,
+ gboolean is_set)
{
- groupPerApp = isSet;
+ xkl_engine_priv(engine, group_per_toplevel_window) = is_set;
}
-Bool XklIsGroupPerApp( void )
+gboolean
+xkl_engine_is_group_per_toplevel_window(XklEngine * engine)
{
- return groupPerApp;
+ return xkl_engine_priv(engine, group_per_toplevel_window);
}
-static void _XklSetSwitchToSecondaryGroup( Bool val )
+static void
+xkl_engine_set_switch_to_secondary_group(XklEngine * engine, gboolean val)
{
- CARD32 propval = (CARD32)val;
- XChangeProperty( _xklDpy, _xklRootWindow, _xklAtoms[XKLAVIER_ALLOW_SECONDARY],
- XA_INTEGER, 32, PropModeReplace,
- (unsigned char*)&propval, 1 );
- XSync( _xklDpy, False );
+ CARD32 propval = (CARD32) val;
+ Display *dpy = xkl_engine_get_display(engine);
+ XChangeProperty(dpy,
+ xkl_engine_priv(engine, root_window),
+ xkl_engine_priv(engine,
+ atoms)[XKLAVIER_ALLOW_SECONDARY],
+ XA_INTEGER, 32, PropModeReplace,
+ (unsigned char *) &propval, 1);
+ XSync(dpy, False);
}
-void XklAllowOneSwitchToSecondaryGroup( void )
+void
+xkl_engine_allow_one_switch_to_secondary_group(XklEngine * engine)
{
- XklDebug( 150, "Setting allowOneSwitchToSecondaryGroup flag\n" );
- _XklSetSwitchToSecondaryGroup( True );
+ xkl_debug(150,
+ "Setting allow_one_switch_to_secondary_group flag\n");
+ xkl_engine_set_switch_to_secondary_group(engine, TRUE);
}
-Bool _XklIsOneSwitchToSecondaryGroupAllowed( void )
+gboolean
+xkl_engine_is_one_switch_to_secondary_group_allowed(XklEngine * engine)
{
- Bool rv = False;
- unsigned char *propval = NULL;
- Atom actualType;
- int actualFormat;
- unsigned long bytesRemaining;
- unsigned long actualItems;
- int result;
+ gboolean rv = FALSE;
+ unsigned char *propval = NULL;
+ Atom actual_type;
+ int actual_format;
+ unsigned long bytes_remaining;
+ unsigned long actual_items;
+ int result;
- result = XGetWindowProperty( _xklDpy, _xklRootWindow,
- _xklAtoms[XKLAVIER_ALLOW_SECONDARY], 0L, 1L,
- False, XA_INTEGER, &actualType, &actualFormat,
- &actualItems, &bytesRemaining,
- &propval );
+ result =
+ XGetWindowProperty(xkl_engine_get_display(engine),
+ xkl_engine_priv(engine, root_window),
+ xkl_engine_priv(engine, atoms)
+ [XKLAVIER_ALLOW_SECONDARY], 0L, 1L, False,
+ XA_INTEGER, &actual_type, &actual_format,
+ &actual_items, &bytes_remaining, &propval);
- if( Success == result )
- {
- if( actualFormat == 32 && actualItems == 1 )
- {
- rv = *(Bool*)propval;
- }
- XFree( propval );
- }
+ if (Success == result) {
+ if (actual_format == 32 && actual_items == 1) {
+ rv = (gboolean) * (Bool *) propval;
+ }
+ XFree(propval);
+ }
- return rv;
+ return rv;
}
-void _XklOneSwitchToSecondaryGroupPerformed( void )
+void
+xkl_engine_one_switch_to_secondary_group_performed(XklEngine * engine)
{
- XklDebug( 150, "Resetting allowOneSwitchToSecondaryGroup flag\n" );
- _XklSetSwitchToSecondaryGroup( False );
+ xkl_debug(150,
+ "Resetting allow_one_switch_to_secondary_group flag\n");
+ xkl_engine_set_switch_to_secondary_group(engine, FALSE);
}
-void XklSetDefaultGroup( int group )
+void
+xkl_engine_set_default_group(XklEngine * engine, gint group)
{
- _xklDefaultGroup = group;
+ xkl_engine_priv(engine, default_group) = group;
}
-int XklGetDefaultGroup( void )
+gint
+xkl_engine_get_default_group(XklEngine * engine)
{
- return _xklDefaultGroup;
+ return xkl_engine_priv(engine, default_group);
}
-void XklSetSecondaryGroupsMask( int mask )
+void
+xkl_engine_set_secondary_groups_mask(XklEngine * engine, guint mask)
{
- _xklSecondaryGroupsMask = mask;
+ xkl_engine_priv(engine, secondary_groups_mask) = mask;
}
-int XklGetSecondaryGroupsMask( void )
+guint
+xkl_engine_get_secondary_groups_mask(XklEngine * engine)
{
- return _xklSecondaryGroupsMask;
+ return xkl_engine_priv(engine, secondary_groups_mask);
}
-int XklRegisterConfigCallback( XklConfigCallback fun, void *data )
+void
+xkl_set_log_appender(XklLogAppender func)
{
- _xklConfigCallback = fun;
- _xklConfigCallbackData = data;
- return 0;
+ log_appender = func;
}
-int XklRegisterStateCallback( XklStateCallback fun, void *data )
+gint
+xkl_engine_start_listen(XklEngine * engine, guint what)
{
- stateCallback = fun;
- stateCallbackData = data;
- return 0;
-}
+ xkl_engine_priv(engine, listener_type) = what;
-int XklRegisterWindowCallback( XklWinCallback fun, void *data )
-{
- winCallback = fun;
- winCallbackData = data;
- return 0;
-}
-
-void XklSetLogAppender( XklLogAppender fun )
-{
- logAppender = fun;
-}
+ if (!
+ (xkl_engine_priv(engine, features) &
+ XKLF_REQUIRES_MANUAL_LAYOUT_MANAGEMENT)
+&& (what & XKLL_MANAGE_LAYOUTS))
+ xkl_debug(0,
+ "The backend does not require manual layout management - "
+ "but it is provided by the application");
-int XklStartListen( int what )
-{
- _xklListenerType = what;
-
- if( !( xklVTable->features & XKLF_REQUIRES_MANUAL_LAYOUT_MANAGEMENT ) &&
- ( what & XKLL_MANAGE_LAYOUTS ) )
- XklDebug( 0, "The backend does not require manual layout management - "
- "but it is provided by the application" );
-
- XklResumeListen( );
- _XklLoadWindowTree( );
- XFlush( _xklDpy );
- return 0;
+ xkl_engine_resume_listen(engine);
+ xkl_engine_load_window_tree(engine);
+ XFlush(xkl_engine_get_display(engine));
+ return 0;
}
-int XklStopListen( void )
+gint
+xkl_engine_stop_listen(XklEngine * engine)
{
- XklPauseListen( );
- return 0;
+ xkl_engine_pause_listen(engine);
+ return 0;
}
-int XklInit( Display * a_dpy )
+XklEngine *
+xkl_engine_get_instance(Display * display)
{
- int scr;
- char *sdl;
- int rv;
-
- sdl = getenv( "XKL_DEBUG" );
- if( sdl != NULL )
- {
- XklSetDebugLevel( atoi( sdl ) );
- }
-
- if( !a_dpy )
- {
- XklDebug( 10, "XklInit : display is NULL ?\n");
- return -1;
- }
-
- _xklDefaultErrHandler =
- XSetErrorHandler( ( XErrorHandler ) _XklErrHandler );
-
- _xklDpy = a_dpy;
- scr = DefaultScreen( _xklDpy );
- _xklRootWindow = RootWindow( _xklDpy, scr );
-
- _xklSkipOneRestore = False;
- _xklDefaultGroup = -1;
- _xklSecondaryGroupsMask = 0L;
- _xklPrevAppWindow = 0;
-
- _xklAtoms[WM_NAME] = XInternAtom( _xklDpy, "WM_NAME", False );
- _xklAtoms[WM_STATE] = XInternAtom( _xklDpy, "WM_STATE", False );
- _xklAtoms[XKLAVIER_STATE] = XInternAtom( _xklDpy, "XKLAVIER_STATE", False );
- _xklAtoms[XKLAVIER_TRANSPARENT] =
- XInternAtom( _xklDpy, "XKLAVIER_TRANSPARENT", False );
- _xklAtoms[XKLAVIER_ALLOW_SECONDARY] =
- XInternAtom( _xklDpy, "XKLAVIER_ALLOW_SECONDARY", False );
+ if (the_engine != NULL) {
+ g_object_ref(G_OBJECT(the_engine));
+ return the_engine;
+ }
- _XklOneSwitchToSecondaryGroupPerformed();
+ if (!display) {
+ xkl_debug(10, "xkl_init : display is NULL ?\n");
+ return NULL;
+ }
- rv = -1;
- XklDebug( 150, "Trying all backends:\n" );
-#ifdef ENABLE_XKB_SUPPORT
- XklDebug( 150, "Trying XKB backend\n" );
- rv = _XklXkbInit();
-#endif
-#ifdef ENABLE_XMM_SUPPORT
- if( rv != 0 )
- {
- XklDebug( 150, "Trying XMM backend\n" );
- rv = _XklXmmInit();
- }
-#endif
- if( rv == 0 )
- {
- XklDebug( 150, "Actual backend: %s\n",
- XklGetBackendName() );
- }
- else
- {
- XklDebug( 0, "All backends failed, last result: %d\n", rv );
- _xklDpy = NULL;
- }
+ the_engine =
+ XKL_ENGINE(g_object_new
+ (xkl_engine_get_type(), "display", display, NULL));
- return ( rv == 0 ) ?
- ( _XklLoadAllInfo() ? 0 : _xklLastErrorCode ) : -1;
+ return the_engine;
}
-int XklTerm( void )
+gboolean
+xkl_engine_grab_key(XklEngine * engine, gint keycode, guint modifiers)
{
- XSetErrorHandler( ( XErrorHandler ) _xklDefaultErrHandler );
- _xklConfigCallback = NULL;
- stateCallback = NULL;
- winCallback = NULL;
+ gboolean ret_code;
+ gchar *keyname;
+ Display *dpy = xkl_engine_get_display(engine);
- logAppender = XklDefaultLogAppender;
- _XklFreeAllInfo( );
-
- return 0;
-}
-
-Bool XklGrabKey( int keycode, unsigned modifiers )
-{
- Bool retCode;
- char *keyName;
+ if (xkl_debug_level >= 100) {
+ keyname =
+ XKeysymToString(XKeycodeToKeysym(dpy, keycode, 0));
+ xkl_debug(100, "Listen to the key %d/(%s)/%d\n", keycode,
+ keyname, modifiers);
+ }
- if( _xklDebugLevel >= 100 )
- {
- keyName = XKeysymToString( XKeycodeToKeysym( _xklDpy, keycode, 0 ) );
- XklDebug( 100, "Listen to the key %d/(%s)/%d\n",
- keycode, keyName, modifiers );
- }
+ if (0 == keycode)
+ return FALSE;
- if( ( KeyCode ) NULL == keycode )
- return False;
+ xkl_engine_priv(engine, last_error_code) = Success;
- _xklLastErrorCode = Success;
+ ret_code =
+ XGrabKey(dpy, keycode, modifiers,
+ xkl_engine_priv(engine, root_window), TRUE,
+ GrabModeAsync, GrabModeAsync);
+ XSync(dpy, False);
- retCode = XGrabKey( _xklDpy, keycode, modifiers, _xklRootWindow,
- True, GrabModeAsync, GrabModeAsync );
- XSync( _xklDpy, False );
+ xkl_debug(100, "XGrabKey recode %d/error %d\n",
+ ret_code, xkl_engine_priv(engine, last_error_code));
- XklDebug( 100, "XGrabKey recode %d/error %d\n", retCode, _xklLastErrorCode );
+ ret_code = (xkl_engine_priv(engine, last_error_code) == Success);
- retCode = ( _xklLastErrorCode == Success );
+ if (!ret_code)
+ xkl_last_error_message = "Could not grab the key";
- if( !retCode )
- _xklLastErrorMsg = "Could not grab the key";
-
- return retCode;
+ return ret_code;
}
-Bool XklUngrabKey( int keycode, unsigned modifiers )
+gboolean
+xkl_engine_ungrab_key(XklEngine * engine, gint keycode, guint modifiers)
{
- if( ( KeyCode ) NULL == keycode )
- return False;
+ if (0 == keycode)
+ return FALSE;
- return Success == XUngrabKey( _xklDpy, keycode, 0, _xklRootWindow );
+ return Success == XUngrabKey(xkl_engine_get_display(engine),
+ keycode, 0,
+ xkl_engine_priv(engine, root_window));
}
-int XklGetNextGroup( void )
+gint
+xkl_engine_get_next_group(XklEngine * engine)
{
- return ( _xklCurState.group + 1 ) % XklGetNumGroups( );
+ gint n = xkl_engine_get_num_groups(engine);
+ return (xkl_engine_priv(engine, curr_state).group + 1) % n;
}
-
-int XklGetPrevGroup( void )
+
+gint
+xkl_engine_get_prev_group(XklEngine * engine)
{
- int n = XklGetNumGroups( );
- return ( _xklCurState.group + n - 1 ) % n;
+ gint n = xkl_engine_get_num_groups(engine);
+ return (xkl_engine_priv(engine, curr_state).group + n - 1) % n;
}
-int XklGetRestoreGroup( void )
+gint
+xkl_engine_get_current_window_group(XklEngine * engine)
{
- XklState state;
- if( _xklCurClient == ( Window ) NULL )
- {
- XklDebug( 150, "cannot restore without current client\n" );
- } else if( XklGetState( _xklCurClient, &state ) )
- {
- return state.group;
- } else
- XklDebug( 150,
- "Unbelievable: current client " WINID_FORMAT
- ", '%s' has no group\n", _xklCurClient,
- _XklGetDebugWindowTitle( _xklCurClient ) );
- return 0;
+ XklState state;
+ if (xkl_engine_priv(engine, curr_toplvl_win) == (Window) NULL) {
+ xkl_debug(150, "cannot restore without current client\n");
+ } else
+ if (xkl_engine_get_toplevel_window_state
+ (engine, xkl_engine_priv(engine, curr_toplvl_win),
+ &state)) {
+ return state.group;
+ } else
+ xkl_debug(150,
+ "Unbelievable: current client " WINID_FORMAT
+ ", '%s' has no group\n",
+ xkl_engine_priv(engine, curr_toplvl_win),
+ xkl_get_debug_window_title(engine,
+ xkl_engine_priv
+ (engine,
+ curr_toplvl_win)));
+ return 0;
}
-void XklSetTransparent( Window win, Bool transparent )
+void
+xkl_engine_set_transparent(XklEngine * engine, Window win,
+ gboolean transparent)
{
- Window appWin;
- Bool wasTransparent;
- XklDebug( 150, "setting transparent flag %d for " WINID_FORMAT "\n",
- transparent, win );
+ Window toplevel_win;
+ xkl_debug(150,
+ "setting transparent flag %d for " WINID_FORMAT "\n",
+ transparent, win);
- if( !_XklGetAppWindow( win, &appWin ) )
- {
- XklDebug( 150, "No app window!\n" );
- /* appWin = win; */
- return;
- }
+ if (!xkl_engine_find_toplevel_window(engine, win, &toplevel_win)) {
+ xkl_debug(150, "No toplevel window!\n");
+ /* toplevel_win = win; */
+ return;
+ }
- wasTransparent = XklIsTransparent( appWin );
- XklDebug( 150, "appwin " WINID_FORMAT " was %stransparent\n", appWin,
- wasTransparent ? "" : "not " );
- if( transparent && !wasTransparent )
- {
- CARD32 prop = 1;
- XChangeProperty( _xklDpy, appWin, _xklAtoms[XKLAVIER_TRANSPARENT],
- XA_INTEGER, 32, PropModeReplace,
- ( const unsigned char * ) &prop, 1 );
- } else if( !transparent && wasTransparent )
- {
- XDeleteProperty( _xklDpy, appWin, _xklAtoms[XKLAVIER_TRANSPARENT] );
- }
+ xkl_engine_set_toplevel_window_transparent(engine, toplevel_win,
+ transparent);
}
-Bool XklIsTransparent( Window win )
+gboolean
+xkl_engine_is_window_transparent(XklEngine * engine, Window win)
{
- Window appWin;
-
- if( !_XklGetAppWindow( win, &appWin ) )
- return False;
- return _XklIsTransparentAppWindow( appWin );
+ Window toplevel_win;
+ if (!xkl_engine_find_toplevel_window(engine, win, &toplevel_win))
+ return FALSE;
+ return xkl_engine_is_toplevel_window_transparent(engine,
+ toplevel_win);
}
/**
- * "Adds" app window to the set of managed windows.
- * Actually, no data structures involved. The only thing we do is save app state
- * and register ourselves us listeners.
- * Note: User's callback is called
+ * Loads the tree recursively.
*/
-void _XklAddAppWindow( Window appWin, Window parent, Bool ignoreExistingState,
- XklState * initState )
-{
- XklState state = *initState;
- int defGroupToUse = -1;
-
- if( appWin == _xklRootWindow )
- XklDebug( 150, "??? root app win ???\n" );
-
- XklDebug( 150, "Trying to add window " WINID_FORMAT "/%s with group %d\n",
- appWin, _XklGetDebugWindowTitle( appWin ), initState->group );
-
- if( !ignoreExistingState )
- {
- Bool have_state = _XklGetAppState( appWin, &state );
-
- if( have_state )
- {
- XklDebug( 150,
- "The window " WINID_FORMAT
- " does not require to be added, it already has the xklavier state \n",
- appWin );
- return;
- }
- }
-
- if( winCallback != NULL )
- defGroupToUse = ( *winCallback ) ( appWin, parent, winCallbackData );
-
- if( defGroupToUse == -1 )
- defGroupToUse = _xklDefaultGroup;
-
- if( defGroupToUse != -1 )
- state.group = defGroupToUse;
-
- _XklSaveAppState( appWin, &state );
- _XklSelectInputMerging( appWin, FocusChangeMask | PropertyChangeMask );
-
- if( defGroupToUse != -1 )
- {
- if( _xklCurClient == appWin )
- {
- if( ( _xklSecondaryGroupsMask & ( 1 << defGroupToUse ) ) != 0 )
- XklAllowOneSwitchToSecondaryGroup();
- XklLockGroup( defGroupToUse );
- }
- }
-
- if( parent == ( Window ) NULL )
- parent = _XklGetRegisteredParent( appWin );
-
- XklDebug( 150, "done\n" );
+gboolean
+xkl_engine_load_window_tree(XklEngine * engine)
+{
+ Window focused;
+ int revert;
+ gboolean retval = TRUE, have_toplevel_win;
+
+ if (xkl_engine_priv(engine, listener_type) &
+ XKLL_MANAGE_WINDOW_STATES)
+ retval =
+ xkl_engine_load_subtree(engine,
+ xkl_engine_priv(engine,
+ root_window),
+ 0, &xkl_engine_priv(engine,
+ curr_state));
+
+ XGetInputFocus(xkl_engine_get_display(engine), &focused, &revert);
+
+ xkl_debug(160, "initially focused: " WINID_FORMAT ", '%s'\n",
+ focused, xkl_get_debug_window_title(engine, focused));
+
+ have_toplevel_win =
+ xkl_engine_find_toplevel_window(engine, focused,
+ &xkl_engine_priv(engine,
+ curr_toplvl_win));
+
+ if (have_toplevel_win) {
+ gboolean have_state =
+ xkl_engine_get_toplevel_window_state(engine,
+ xkl_engine_priv
+ (engine,
+ curr_toplvl_win),
+ &xkl_engine_priv
+ (engine,
+ curr_state));
+ xkl_debug(160,
+ "initial toplevel: " WINID_FORMAT
+ ", '%s' %s state %d/%X\n",
+ xkl_engine_priv(engine, curr_toplvl_win),
+ xkl_get_debug_window_title(engine,
+ xkl_engine_priv
+ (engine,
+ curr_toplvl_win)),
+ (have_state ? "with" : "without"),
+ (have_state ?
+ xkl_engine_priv(engine, curr_state).group : -1),
+ (have_state ?
+ xkl_engine_priv(engine,
+ curr_state).indicators : -1));
+ } else {
+ xkl_debug(160,
+ "Could not find initial app. "
+ "Probably, focus belongs to some WM service window. "
+ "Will try to survive:)");
+ }
+
+ return retval;
+}
+
+void
+_xkl_debug(const gchar file[], const gchar function[], gint level,
+ const gchar format[], ...)
+{
+ va_list lst;
+
+ if (level > xkl_debug_level)
+ return;
+
+ va_start(lst, format);
+ if (log_appender != NULL)
+ (*log_appender) (file, function, level, format, lst);
+ va_end(lst);
+}
+
+void
+xkl_default_log_appender(const gchar file[], const gchar function[],
+ gint level, const gchar format[], va_list args)
+{
+ time_t now = time(NULL);
+ fprintf(stdout, "[%08ld,%03d,%s:%s/] \t", now, level, file,
+ function);
+ vfprintf(stdout, format, args);
}
/**
- * Checks the window and goes up
+ * Just selects some events from the window.
*/
-Bool _XklGetAppWindowBottomToTop( Window win, Window * appWin_return )
+void
+xkl_engine_select_input(XklEngine * engine, Window win, gulong mask)
{
- Window parent = ( Window ) NULL, rwin = ( Window ) NULL, *children = NULL;
- unsigned int num = 0;
-
- if( win == ( Window ) NULL || win == _xklRootWindow )
- {
- *appWin_return = win;
- _xklLastErrorMsg = "The window is either 0 or root";
- return False;
- }
-
- if( _XklHasWmState( win ) )
- {
- *appWin_return = win;
- return True;
- }
-
- _xklLastErrorCode =
- _XklStatusQueryTree( _xklDpy, win, &rwin, &parent, &children, &num );
-
- if( _xklLastErrorCode != Success )
- {
- *appWin_return = ( Window ) NULL;
- return False;
- }
+ if (xkl_engine_priv(engine, root_window) == win)
+ xkl_debug(160,
+ "Someone is looking for %lx on root window ***\n",
+ mask);
- if( children != NULL )
- XFree( children );
-
- return _XklGetAppWindowBottomToTop( parent, appWin_return );
-}
-
-/**
- * Recursively finds "App window" (window with WM_STATE) for given window.
- * First, checks the window itself
- * Then, for first level of recursion, checks childen,
- * Then, goes to parent.
- * NOTE: root window cannot be "App window" under normal circumstances
- */
-Bool _XklGetAppWindow( Window win, Window * appWin_return )
-{
- Window parent = ( Window ) NULL,
- rwin = ( Window ) NULL, *children = NULL, *child;
- unsigned int num = 0;
- Bool rv;
-
- if( win == ( Window ) NULL || win == _xklRootWindow )
- {
- *appWin_return = ( Window ) NULL;
- _xklLastErrorMsg = "The window is either 0 or root";
- XklDebug( 150,
- "Window " WINID_FORMAT
- " is either 0 or root so could not get the app window for it\n",
- win );
- return False;
- }
-
- if( _XklHasWmState( win ) )
- {
- *appWin_return = win;
- return True;
- }
-
- _xklLastErrorCode =
- _XklStatusQueryTree( _xklDpy, win, &rwin, &parent, &children, &num );
-
- if( _xklLastErrorCode != Success )
- {
- *appWin_return = ( Window ) NULL;
- XklDebug( 150,
- "Could not get tree for window " WINID_FORMAT
- " so could not get the app window for it\n", win );
- return False;
- }
-
- /**
- * Here we first check the children (in case win is just above some "App Window")
- * and then go upstairs
- */
- child = children;
- while( num )
- {
- if( _XklHasWmState( *child ) )
- {
- *appWin_return = *child;
- if( children != NULL )
- XFree( children );
- return True;
- }
- child++;
- num--;
- }
-
- if( children != NULL )
- XFree( children );
-
- rv = _XklGetAppWindowBottomToTop( parent, appWin_return );
-
- if( !rv )
- XklDebug( 200, "Could not get the app window for " WINID_FORMAT "/%s\n",
- win, _XklGetDebugWindowTitle( win ) );
-
- return rv;
+ XSelectInput(xkl_engine_get_display(engine), win, mask);
}
-/**
- * Loads the tree recursively.
- */
-Bool _XklLoadWindowTree( void )
+void
+xkl_engine_select_input_merging(XklEngine * engine, Window win,
+ gulong mask)
{
- Window focused;
- int revert;
- Bool retval = True, haveAppWindow;
+ XWindowAttributes attrs;
+ gulong oldmask = 0L, newmask;
+ memset(&attrs, 0, sizeof(attrs));
+ if (XGetWindowAttributes
+ (xkl_engine_get_display(engine), win, &attrs))
+ oldmask = attrs.your_event_mask;
- if( _xklListenerType & XKLL_MANAGE_WINDOW_STATES )
- retval = _XklLoadSubtree( _xklRootWindow, 0, &_xklCurState );
+ newmask = oldmask | mask;
+ if (newmask != oldmask)
+ xkl_engine_select_input(engine, win, newmask);
+}
- XGetInputFocus( _xklDpy, &focused, &revert );
+void
+xkl_engine_try_call_state_func(XklEngine * engine,
+ XklEngineStateChange change_type,
+ XklState * old_state)
+{
+ gint group = xkl_engine_priv(engine, curr_state).group;
+ gboolean restore = old_state->group == group;
- XklDebug( 160, "initially focused: " WINID_FORMAT ", '%s'\n",
- focused, _XklGetDebugWindowTitle( focused ) );
+ xkl_debug(150,
+ "change_type: %d, group: %d, secondary_group_mask: %X, allowsecondary: %d\n",
+ change_type, group, xkl_engine_priv(engine,
+ secondary_groups_mask),
+ xkl_engine_is_one_switch_to_secondary_group_allowed
+ (engine));
- haveAppWindow = _XklGetAppWindow( focused, &_xklCurClient );
+ if (change_type == GROUP_CHANGED) {
+ if (!restore) {
+ if ((xkl_engine_priv(engine, secondary_groups_mask)
+ & (1 << group)) != 0
+ &&
+ !xkl_engine_is_one_switch_to_secondary_group_allowed
+ (engine)) {
+ xkl_debug(150, "secondary -> go next\n");
+ group = xkl_engine_get_next_group(engine);
+ xkl_engine_lock_group(engine, group);
+ return; /* we do not need to revalidate */
+ }
+ }
+ xkl_engine_one_switch_to_secondary_group_performed(engine);
+ }
- if( haveAppWindow )
- {
- Bool haveState = _XklGetAppState( _xklCurClient, &_xklCurState );
- XklDebug( 160,
- "initial _xklCurClient: " WINID_FORMAT
- ", '%s' %s state %d/%X\n", _xklCurClient,
- _XklGetDebugWindowTitle( _xklCurClient ),
- ( haveState ? "with" : "without" ),
- ( haveState ? _xklCurState.group : -1 ),
- ( haveState ? _xklCurState.indicators : -1 ) );
- } else
- {
- XklDebug( 160,
- "could not find initial app. Probably, focus belongs to some WM service window. Will try to survive:)" );
- }
+ g_signal_emit_by_name(engine, "X-state-changed", change_type,
+ xkl_engine_priv(engine, curr_state).group,
+ restore);
- return retval;
}
-void _XklDebug( const char file[], const char function[], int level,
- const char format[], ... )
+void
+xkl_engine_ensure_vtable_inited(XklEngine * engine)
{
- va_list lst;
-
- if( level > _xklDebugLevel )
- return;
-
- va_start( lst, format );
- if( logAppender != NULL )
- ( *logAppender ) ( file, function, level, format, lst );
- va_end( lst );
+ char *p;
+ if (xkl_engine_priv(engine, backend_id) == NULL) {
+ xkl_debug(0, "ERROR: XKL VTable is NOT initialized.\n");
+ /* force the crash! */
+ p = NULL;
+ *p = '\0';
+ }
}
-void XklDefaultLogAppender( const char file[], const char function[],
- int level, const char format[], va_list args )
+const gchar *
+xkl_engine_get_backend_name(XklEngine * engine)
{
- time_t now = time( NULL );
- fprintf( stdout, "[%08ld,%03d,%s:%s/] \t", now, level, file, function );
- vfprintf( stdout, format, args );
+ return xkl_engine_priv(engine, backend_id);
}
-/**
- * Gets the state from the window property
- */
-Bool _XklGetAppState( Window appWin, XklState * state_return )
-{
- Atom type_ret;
- int format_ret;
- unsigned long nitems, rest;
- CARD32 *prop = NULL;
- Bool ret = False;
-
- int grp = -1;
- unsigned inds = 0;
-
- if( ( XGetWindowProperty
- ( _xklDpy, appWin, _xklAtoms[XKLAVIER_STATE], 0L,
- XKLAVIER_STATE_PROP_LENGTH, False,
- XA_INTEGER, &type_ret, &format_ret, &nitems, &rest,
- ( unsigned char ** ) ( void * ) &prop ) == Success )
- && ( type_ret == XA_INTEGER ) && ( format_ret == 32 ) )
- {
- grp = prop[0];
- if( grp >= XklGetNumGroups( ) || grp < 0 )
- grp = 0;
-
- inds = prop[1];
-
- if( state_return != NULL )
- {
- state_return->group = grp;
- state_return->indicators = inds;
- }
- if( prop != NULL )
- XFree( prop );
-
- ret = True;
- }
-
- if( ret )
- XklDebug( 150,
- "Appwin " WINID_FORMAT
- ", '%s' has the group %d, indicators %X\n", appWin,
- _XklGetDebugWindowTitle( appWin ), grp, inds );
- else
- XklDebug( 150, "Appwin " WINID_FORMAT ", '%s' does not have state\n",
- appWin, _XklGetDebugWindowTitle( appWin ) );
-
- return ret;
-}
-
-/**
- * Deletes the state from the window properties
- */
-void _XklDelAppState( Window appWin )
+guint
+xkl_engine_get_features(XklEngine * engine)
{
- XDeleteProperty( _xklDpy, appWin, _xklAtoms[XKLAVIER_STATE] );
+ return xkl_engine_priv(engine, features);
}
-/**
- * Saves the state into the window properties
- */
-void _XklSaveAppState( Window appWin, XklState * state )
+void
+xkl_engine_reset_all_info(XklEngine * engine, const gchar reason[])
{
- CARD32 prop[XKLAVIER_STATE_PROP_LENGTH];
-
- prop[0] = state->group;
- prop[1] = state->indicators;
-
- XChangeProperty( _xklDpy, appWin, _xklAtoms[XKLAVIER_STATE], XA_INTEGER,
- 32, PropModeReplace, ( const unsigned char * ) prop,
- XKLAVIER_STATE_PROP_LENGTH );
-
- XklDebug( 160,
- "Saved the group %d, indicators %X for appwin " WINID_FORMAT "\n",
- state->group, state->indicators, appWin );
+ xkl_debug(150, "Resetting all the cached info, reason: [%s]\n",
+ reason);
+ xkl_engine_ensure_vtable_inited(engine);
+ if (!xkl_engine_vcall(engine, if_cached_info_equals_actual)
+ (engine)) {
+ xkl_engine_vcall(engine, free_all_info) (engine);
+ xkl_engine_vcall(engine, load_all_info) (engine);
+ } else
+ xkl_debug(100,
+ "NOT Resetting the cache: same configuration\n");
}
/**
- * Just selects some events from the window.
+ * Calling through vtable
*/
-void _XklSelectInput( Window win, long mask )
+const gchar **
+xkl_engine_groups_get_names(XklEngine * engine)
{
- if( _xklRootWindow == win )
- XklDebug( 160,
- "Someone is looking for %lx on root window ***\n",
- mask );
-
- XSelectInput( _xklDpy, win, mask );
+ xkl_engine_ensure_vtable_inited(engine);
+ return xkl_engine_vcall(engine, get_groups_names) (engine);
}
-void _XklSelectInputMerging( Window win, long mask )
+guint
+xkl_engine_get_num_groups(XklEngine * engine)
{
- XWindowAttributes attrs;
- long oldmask = 0L, newmask;
- memset( &attrs, 0, sizeof( attrs ) );
- if( XGetWindowAttributes( _xklDpy, win, &attrs ) )
- oldmask = attrs.your_event_mask;
-
- newmask = oldmask | mask;
- if( newmask != oldmask )
- _XklSelectInput( win, newmask );
+ xkl_engine_ensure_vtable_inited(engine);
+ return xkl_engine_vcall(engine, get_num_groups) (engine);
}
-void _XklTryCallStateCallback( XklStateChange changeType,
- XklState * oldState )
+void
+xkl_engine_lock_group(XklEngine * engine, int group)
{
- int group = _xklCurState.group;
- Bool restore = oldState->group == group;
-
- XklDebug( 150,
- "changeType: %d, group: %d, secondaryGroupMask: %X, allowsecondary: %d\n",
- changeType, group, _xklSecondaryGroupsMask,
- _XklIsOneSwitchToSecondaryGroupAllowed() );
-
- if( changeType == GROUP_CHANGED )
- {
- if( !restore )
- {
- if( ( _xklSecondaryGroupsMask & ( 1 << group ) ) != 0 &&
- !_XklIsOneSwitchToSecondaryGroupAllowed() )
- {
- XklDebug( 150, "secondary -> go next\n" );
- group = XklGetNextGroup( );
- XklLockGroup( group );
- return; /* we do not need to revalidate */
- }
- }
- _XklOneSwitchToSecondaryGroupPerformed();
- }
- if( stateCallback != NULL )
- {
-
- ( *stateCallback ) ( changeType, _xklCurState.group,
- restore, stateCallbackData );
- }
+ xkl_engine_ensure_vtable_inited(engine);
+ xkl_engine_vcall(engine, lock_group) (engine, group);
}
-Bool _XklIsTransparentAppWindow( Window appWin )
+gint
+xkl_engine_pause_listen(XklEngine * engine)
{
- Atom type_ret;
- int format_ret;
- unsigned long nitems, rest;
- CARD32 *prop = NULL;
- if( ( XGetWindowProperty
- ( _xklDpy, appWin, _xklAtoms[XKLAVIER_TRANSPARENT], 0L, 1, False,
- XA_INTEGER, &type_ret, &format_ret, &nitems, &rest,
- ( unsigned char ** ) ( void * ) &prop ) == Success )
- && ( type_ret == XA_INTEGER ) && ( format_ret == 32 ) )
- {
- if( prop != NULL )
- XFree( prop );
- return True;
- }
- return False;
+ xkl_engine_ensure_vtable_inited(engine);
+ return xkl_engine_vcall(engine, pause_listen) (engine);
}
-void _XklEnsureVTableInited( void )
+gint
+xkl_engine_resume_listen(XklEngine * engine)
{
- char *p;
- if ( xklVTable == NULL )
- {
- XklDebug( 0, "ERROR: XKL VTable is NOT initialized.\n" );
- /* force the crash! */
- p = NULL; *p = '\0';
- }
-}
+ xkl_engine_ensure_vtable_inited(engine);
+ xkl_debug(150, "listenerType: %x\n",
+ xkl_engine_priv(engine, listener_type));
+ if (xkl_engine_vcall(engine, resume_listen) (engine))
+ return 1;
-const char *XklGetBackendName( void )
-{
- return xklVTable->id;
-}
+ xkl_engine_select_input_merging(engine,
+ xkl_engine_priv(engine,
+ root_window),
+ SubstructureNotifyMask |
+ PropertyChangeMask);
-int XklGetBackendFeatures( void )
-{
- return xklVTable->features;
+ xkl_engine_vcall(engine,
+ get_server_state) (engine,
+ &xkl_engine_priv(engine,
+ curr_state));
+ return 0;
}
-void _XklResetAllInfo( const char reason[] )
+guint
+xkl_engine_get_max_num_groups(XklEngine * engine)
{
- XklDebug( 150, "Resetting all the cached info, reason: [%s]\n", reason );
- _XklEnsureVTableInited();
- if( !(*xklVTable->xklIfCachedInfoEqualsActualHandler)() )
- {
- (*xklVTable->xklFreeAllInfoHandler)();
- (*xklVTable->xklLoadAllInfoHandler)();
- } else
- XklDebug( 100, "NOT Resetting the cache: same configuration\n" );
+ xkl_engine_ensure_vtable_inited(engine);
+ return xkl_engine_vcall(engine, get_max_num_groups) (engine);
}
-/**
- * Calling through vtable
- */
-const char **XklGetGroupNames( void )
+XklEngine *
+xkl_get_the_engine()
{
- _XklEnsureVTableInited();
- return (*xklVTable->xklGetGroupNamesHandler)();
+ return the_engine;
}
-unsigned XklGetNumGroups( void )
-{
- _XklEnsureVTableInited();
- return (*xklVTable->xklGetNumGroupsHandler)();
-}
+G_DEFINE_TYPE(XklEngine, xkl_engine, G_TYPE_OBJECT)
-void XklLockGroup( int group )
+static GObject *
+xkl_engine_constructor(GType type,
+ guint n_construct_properties,
+ GObjectConstructParam * construct_properties)
{
- _XklEnsureVTableInited();
- (*xklVTable->xklLockGroupHandler)( group );
-}
+ GObject *obj;
-int XklPauseListen( void )
-{
- _XklEnsureVTableInited();
- return (*xklVTable->xklPauseListenHandler)();
-}
+ {
+ /* Invoke parent constructor. */
+ XklEngineClass *klass;
+ klass =
+ XKL_ENGINE_CLASS(g_type_class_peek(XKL_TYPE_ENGINE));
+ obj =
+ parent_class->constructor(type, n_construct_properties,
+ construct_properties);
+ }
-int XklResumeListen( void )
-{
- _XklEnsureVTableInited();
- XklDebug( 150, "listenerType: %x\n", _xklListenerType );
- if( (*xklVTable->xklResumeListenHandler)() )
- return 1;
-
- _XklSelectInputMerging( _xklRootWindow,
- SubstructureNotifyMask | PropertyChangeMask );
- _XklEnsureVTableInited();
- (*xklVTable->xklGetRealStateHandler)( &_xklCurState );
- return 0;
-}
+ XklEngine *engine = XKL_ENGINE(obj);
-Bool _XklLoadAllInfo( void )
-{
- _XklEnsureVTableInited();
- return (*xklVTable->xklLoadAllInfoHandler)();
-}
+ Display *display =
+ (Display *) g_value_peek_pointer(construct_properties[0].
+ value);
-void _XklFreeAllInfo( void )
-{
- _XklEnsureVTableInited();
- (*xklVTable->xklFreeAllInfoHandler)();
-}
+ xkl_engine_priv(engine, display) = display;
-unsigned XklGetMaxNumGroups( void )
-{
- _XklEnsureVTableInited();
- return (*xklVTable->xklGetMaxNumGroupsHandler)();
-}
+ int scr;
+
+ xkl_engine_priv(engine, default_error_handler) =
+ XSetErrorHandler((XErrorHandler) xkl_process_error);
+
+ scr = DefaultScreen(display);
+ xkl_engine_priv(engine, root_window) = RootWindow(display, scr);
+
+ xkl_engine_priv(engine, skip_one_restore) = FALSE;
+ xkl_engine_priv(engine, default_group) = -1;
+ xkl_engine_priv(engine, secondary_groups_mask) = 0L;
+ xkl_engine_priv(engine, prev_toplvl_win) = 0;
+ xkl_engine_priv(engine, atoms)[WM_NAME] =
+ XInternAtom(display, "WM_NAME", False);
+ xkl_engine_priv(engine, atoms)[WM_STATE] =
+ XInternAtom(display, "WM_STATE", False);
+ xkl_engine_priv(engine, atoms)[XKLAVIER_STATE] =
+ XInternAtom(display, "XKLAVIER_STATE", False);
+ xkl_engine_priv(engine, atoms)[XKLAVIER_TRANSPARENT] =
+ XInternAtom(display, "XKLAVIER_TRANSPARENT", False);
+ xkl_engine_priv(engine, atoms)[XKLAVIER_ALLOW_SECONDARY] =
+ XInternAtom(display, "XKLAVIER_ALLOW_SECONDARY", False);
+
+ xkl_engine_one_switch_to_secondary_group_performed(engine);
+
+ gint rv = -1;
+ xkl_debug(150, "Trying all backends:\n");
+#ifdef ENABLE_XKB_SUPPORT
+ xkl_debug(150, "Trying XKB backend\n");
+ rv = xkl_xkb_init(engine);
+#endif
+#ifdef ENABLE_XMM_SUPPORT
+ if (rv != 0) {
+ xkl_debug(150, "Trying XMM backend\n");
+ rv = xkl_xmm_init(engine);
+ }
+#endif
+ if (rv == 0) {
+ xkl_debug(150, "Actual backend: %s\n",
+ xkl_engine_get_backend_name(engine));
+ } else {
+ xkl_debug(0, "All backends failed, last result: %d\n", rv);
+ xkl_engine_priv(engine, display) = NULL;
+ g_object_unref(G_OBJECT(engine));
+ return NULL;
+ }
+
+ xkl_engine_ensure_vtable_inited(engine);
+ if (!xkl_engine_vcall(engine, load_all_info) (engine)) {
+ g_object_unref(G_OBJECT(engine));
+ return NULL;
+ }
+
+ return obj;
+}
+
+static void
+xkl_engine_init(XklEngine * engine)
+{
+ engine->priv = g_new0(XklEnginePrivate, 1);
+}
+
+static void
+xkl_engine_set_property(GObject * object,
+ guint property_id,
+ const GValue * value, GParamSpec * pspec)
+{
+}
+
+static void
+xkl_engine_get_property(GObject * object,
+ guint property_id,
+ GValue * value, GParamSpec * pspec)
+{
+ XklEngine *engine = XKL_ENGINE(object);
+
+ switch (property_id) {
+ case PROP_DISPLAY:
+ g_value_set_pointer(value, xkl_engine_get_display(engine));
+ break;
+ case PROP_BACKEND_NAME:
+ g_value_set_string(value,
+ xkl_engine_priv(engine, backend_id));
+ break;
+ case PROP_FEATURES:
+ g_value_set_flags(value,
+ xkl_engine_priv(engine, features));
+ break;
+ case PROP_MAX_NUM_GROUPS:
+ g_value_set_uint(value,
+ xkl_engine_vcall(engine,
+ get_max_num_groups)
+ (engine));
+ break;
+ case PROP_NUM_GROUPS:
+ g_value_set_uint(value,
+ xkl_engine_vcall(engine, get_num_groups)
+ (engine));
+ break;
+ case PROP_DEFAULT_GROUP:
+ g_value_set_uint(value,
+ xkl_engine_priv(engine, default_group));
+ break;
+ case PROP_SECONDARY_GROUPS_MASK:
+ g_value_set_uint(value,
+ xkl_engine_priv(engine,
+ secondary_groups_mask));
+ break;
+ case PROP_INDICATORS_HANDLING:
+ g_value_set_boolean(value,
+ xkl_engine_priv(engine,
+ handle_indicators));
+ break;
+ }
+}
+
+static void
+xkl_engine_finalize(GObject * obj)
+{
+ XklEngine *engine = (XklEngine *) obj;
+
+ XSetErrorHandler((XErrorHandler)
+ xkl_engine_priv(engine, default_error_handler));
+
+ xkl_engine_ensure_vtable_inited(engine);
+ xkl_engine_vcall(engine, free_all_info) (engine);
+
+ xkl_engine_vcall(engine, finalize) (engine);
+
+ gpointer backend = xkl_engine_priv(engine, backend);
+ if (backend != NULL)
+ g_free(backend);
+ g_free(engine->priv);
+
+ G_OBJECT_CLASS(parent_class)->finalize(obj);
+}
+
+static void
+xkl_engine_class_init(XklEngineClass * klass)
+{
+ static GFlagsValue feature_flags[] = {
+ {XKLF_CAN_TOGGLE_INDICATORS, "XKLF_CAN_TOGGLE_INDICATORS",
+ NULL},
+ {XKLF_CAN_OUTPUT_CONFIG_AS_ASCII,
+ "XKLF_CAN_OUTPUT_CONFIG_AS_ASCII", NULL},
+ {XKLF_CAN_OUTPUT_CONFIG_AS_BINARY,
+ "XKLF_CAN_OUTPUT_CONFIG_AS_BINARY", NULL},
+ {XKLF_MULTIPLE_LAYOUTS_SUPPORTED,
+ "XKLF_MULTIPLE_LAYOUTS_SUPPORTED", NULL},
+ {XKLF_REQUIRES_MANUAL_LAYOUT_MANAGEMENT,
+ "XKLF_REQUIRES_MANUAL_LAYOUT_MANAGEMENT", NULL},
+ {0, NULL, NULL}
+ };
+ static GEnumValue state_change_values[] = {
+ {GROUP_CHANGED, "GROUP_CHANGED", NULL},
+ {INDICATORS_CHANGED, "INDICATORS_CHANGED", NULL},
+ {0, NULL, NULL}
+ };
+
+ GObjectClass *object_class;
+
+ object_class = (GObjectClass *) klass;
+ parent_class = g_type_class_peek_parent(object_class);
+
+ object_class->constructor = xkl_engine_constructor;
+ object_class->finalize = xkl_engine_finalize;
+ object_class->set_property = xkl_engine_set_property;
+ object_class->get_property = xkl_engine_get_property;
+
+ GParamSpec *display_param_spec = g_param_spec_pointer("display",
+ "Display",
+ "X Display pointer",
+ G_PARAM_CONSTRUCT_ONLY
+ |
+ G_PARAM_READWRITE);
+
+ GParamSpec *backend_name_param_spec =
+ g_param_spec_string("backendName",
+ "backendName",
+ "Backend name",
+ NULL,
+ G_PARAM_READABLE);
+
+ GType features_type = g_flags_register_static("XklEngineFeatures",
+ feature_flags);
+
+ GType state_change_type =
+ g_enum_register_static("XklEngineStateChangeType",
+ state_change_values);
+
+ GParamSpec *features_param_spec = g_param_spec_flags("features",
+ "Features",
+ "Backend features",
+ features_type,
+ 0,
+ G_PARAM_READABLE);
+ GParamSpec *max_num_groups_param_spec =
+ g_param_spec_uint("max-num-groups",
+ "maxNumGroups",
+ "Max number of groups",
+ 0, 0x100, 0,
+ G_PARAM_READABLE);
+
+ GParamSpec *num_groups_param_spec = g_param_spec_uint("num-groups",
+ "numGroups",
+ "Current number of groups",
+ 0, 0x100, 0,
+ G_PARAM_READABLE);
+
+ GParamSpec *default_group_param_spec =
+ g_param_spec_uint("default-group",
+ "defaultGroup",
+ "Default group",
+ 0, 0x100, 0,
+ G_PARAM_READABLE);
+
+ GParamSpec *secondary_groups_mask_param_spec =
+ g_param_spec_uint("secondary-groups-mask",
+ "secondaryGroupsMask",
+ "Secondary groups mask",
+ 0, 0x100, 0,
+ G_PARAM_READABLE);
+
+ GParamSpec *indicators_handling_param_spec =
+ g_param_spec_boolean("indicators-handling",
+ "indicatorsHandling",
+ "Whether engine should handle indicators",
+ FALSE,
+ G_PARAM_READABLE);
+
+ g_object_class_install_property(object_class,
+ PROP_DISPLAY, display_param_spec);
+ g_object_class_install_property(object_class,
+ PROP_BACKEND_NAME,
+ backend_name_param_spec);
+ g_object_class_install_property(object_class, PROP_FEATURES,
+ features_param_spec);
+ g_object_class_install_property(object_class, PROP_MAX_NUM_GROUPS,
+ max_num_groups_param_spec);
+ g_object_class_install_property(object_class, PROP_NUM_GROUPS,
+ num_groups_param_spec);
+ g_object_class_install_property(object_class, PROP_DEFAULT_GROUP,
+ default_group_param_spec);
+ g_object_class_install_property(object_class,
+ PROP_SECONDARY_GROUPS_MASK,
+ secondary_groups_mask_param_spec);
+ g_object_class_install_property(object_class,
+ PROP_INDICATORS_HANDLING,
+ indicators_handling_param_spec);
+
+
+ g_signal_new("X-config-changed", XKL_TYPE_ENGINE,
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(XklEngineClass,
+ config_notify),
+ NULL, NULL, xkl_engine_VOID__VOID, G_TYPE_NONE, 0);
+
+ g_signal_new("new-toplevel-window", XKL_TYPE_ENGINE,
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(XklEngineClass,
+ new_window_notify),
+ NULL, NULL, xkl_engine_INT__LONG_LONG,
+ G_TYPE_INT, 2, G_TYPE_LONG, G_TYPE_LONG);
+
+ g_signal_new("X-state-changed", XKL_TYPE_ENGINE,
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(XklEngineClass,
+ state_notify),
+ NULL, NULL,
+ xkl_engine_VOID__FLAGS_INT_BOOLEAN,
+ G_TYPE_NONE, 3, state_change_type, G_TYPE_INT,
+ G_TYPE_BOOLEAN);
+
+ /* 2 Windows passed */
+ /* static stuff initialized */
+
+ const gchar *sdl = g_getenv("XKL_DEBUG");
+
+ if (sdl != NULL) {
+ xkl_set_debug_level(atoi(sdl));
+ }
+}
diff --git a/libxklavier/xklavier.h b/libxklavier/xklavier.h
index 000f523..5dcb8c5 100644
--- a/libxklavier/xklavier.h
+++ b/libxklavier/xklavier.h
@@ -1,7 +1,3 @@
-/**
- * @file xklavier.h
- */
-
#ifndef __XKLAVIER_H__
#define __XKLAVIER_H__
@@ -9,542 +5,117 @@
#include <X11/Xlib.h>
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
- typedef enum
- {
-/**
- * Group was changed
- */
- GROUP_CHANGED,
-/**
- * Indicators were changed
- */
- INDICATORS_CHANGED
- }
- XklStateChange;
-
-/**
- * Backend allows to toggls indicators on/off
- */
-#define XKLF_CAN_TOGGLE_INDICATORS 0x01
-
-/**
- * Backend allows to write ascii representation of the configuration
- */
-#define XKLF_CAN_OUTPUT_CONFIG_AS_ASCII 0x02
-
-/**
- * Backend allows to write binary representation of the configuration
- */
-#define XKLF_CAN_OUTPUT_CONFIG_AS_BINARY 0x04
-
-/**
- * Backend supports multiple layouts
- */
-#define XKLF_MULTIPLE_LAYOUTS_SUPPORTED 0x08
-
-/**
- * Backend requires manual configuration,
- * some daemon should do
- * XklStartListen( XKLL_MANAGE_LAYOUTS );
- */
-#define XKLF_REQUIRES_MANUAL_LAYOUT_MANAGEMENT 0x10
-
-/**
- * XKB state. Can be global or per-window
- */
- typedef struct
- {
-/** selected group */
- int group;
-/** set of active indicators */
- unsigned indicators;
- }
- XklState;
-
-/**
- * @defgroup xklinitterm Library initialization and termination
- * @{
- */
-
-/**
- * Initializes internal structures. Does not start actual listening though.
- * Some apps can use Xklavier for information retrieval but not for actual
- * processing.
- * @param dpy is an open display, will be tested for XKB extension
- * @return 0 if OK, otherwise last X error
- * (special case: -1 if XKB extension is not present)
- */
- extern int XklInit( Display * dpy );
-
-/**
- * Terminates everything...
- */
- extern int XklTerm( void );
-
-/**
- * What kind of backend if used
- * @return some string id of the backend
- */
- extern const char *XklGetBackendName( void );
-
-/**
- * Provides information regarding available backend features
- * (combination of XKLF_* constants)
- * @return ORed XKLF_* constants
- */
- extern int XklGetBackendFeatures( void );
-
-/**
- * Provides the information on maximum number of simultaneously supported
- * groups (layouts)
- * @return maximum number of the groups in configuration,
- * 0 if no restrictions.
- */
- extern unsigned XklGetMaxNumGroups( void );
-/** @} */
-
-/**
- * @defgroup xkbevents XKB event handling and management
- * @{
- */
-
-/**
- * The listener process should handle the per-window states
- * and all the related activity
- */
-#define XKLL_MANAGE_WINDOW_STATES 0x01
-
-/**
- * Just track the state and pass it to the application above.
- */
-#define XKLL_TRACK_KEYBOARD_STATE 0x02
-
-/**
- * The listener process should help backend to maintain the configuration
- * (manually switch layouts etc).
- */
-#define XKLL_MANAGE_LAYOUTS 0x04
-
-/**
- * Starts listening for XKB-related events
- * @param what any combination of XKLL_* constants
- * @return 0
- */
- extern int XklStartListen( int what );
-
-/**
- * Stops listening for XKB-related events
- * @return 0
- */
- extern int XklStopListen( void );
-
-/**
- * Temporary pauses listening for XKB-related events
- * @return 0
- */
- extern int XklPauseListen( void );
-
-/**
- * Resumes listening for XKB-related events
- * @return 0
- */
- extern int XklResumeListen( void );
-
-/**
- * Grabs some key
- * @param keycode is a keycode
- * @param modifiers is a bitmask of modifiers
- * @return True on success
- */
- extern Bool XklGrabKey( int keycode, unsigned modifiers );
-
-/**
- * Ungrabs some key
- * @param keycode is a keycode
- * @param modifiers is a bitmask of modifiers
- * @return True on success
- */
- extern Bool XklUngrabKey( int keycode, unsigned modifiers );
-
-/**
- * Processes X events. Should be included into the main event cycle of an
- * application. One of the most important functions.
- * @param evt is delivered X event
- * @return 0 if the event it processed - 1 otherwise
- * @see XklStartListen
- */
- extern int XklFilterEvents( XEvent * evt );
-
-/**
- * Allows to switch (once) to the secondary group
- */
- extern void XklAllowOneSwitchToSecondaryGroup( void );
-
-/** @} */
-
-/**
- * @defgroup currents Current state of the library
- * @{
- */
-
-/**
- * @return currently focused window
- */
- extern Window XklGetCurrentWindow( void );
-
-/**
- * @return current state of the keyboard (in XKB terms).
- * Returned value is a statically allocated buffer, should not be freed.
- */
- extern XklState *XklGetCurrentState( void );
-
-/** @} */
-
-/**
- * @defgroup wininfo Per-window information
- * @{
- */
-
-/**
- * @return the window title of some window or NULL.
- * If not NULL, it should be freed with XFree
- */
- extern unsigned char *XklGetWindowTitle( Window w );
-
-/**
- * Finds the state for a given window (for its "App window").
- * @param win is a target window
- * @param state_return is a structure to store the state
- * @return True on success, otherwise False
- * (the error message can be obtained using XklGetLastError).
- */
- extern Bool XklGetState( Window win, XklState * state_return );
-
-/**
- * Drops the state of a given window (of its "App window").
- * @param win is a target window
- */
- extern void XklDelState( Window win );
-
-/**
- * Stores ths state for a given window
- * @param win is a target window
- * @param state is a new state of the window
- */
- extern void XklSaveState( Window win, XklState * state );
-
-/**
- * Sets the "transparent" flag. It means focus switching onto
- * this window will never change the state.
- * @param win is the window do set the flag for.
- * @param transparent - if true, the windows is transparent.
- * @see XklIsTranspatent
- */
- extern void XklSetTransparent( Window win, Bool transparent );
-
-/**
- * Returns "transparent" flag.
- * @param win is the window to get the transparent flag from.
- * @see XklSetTranspatent
- */
- extern Bool XklIsTransparent( Window win );
-
-/**
- * Checks whether 2 windows have the same App Window
- * @param win1 is first window
- * @param win2 is second window
- * @return True is windows are in the same application
- */
- extern Bool XklIsSameApp( Window win1, Window win2 );
-
-/** @} */
-
-/**
- * @defgroup xkbinfo Various XKB configuration info
- * @{
- */
-
-/**
- * @return the total number of groups in the current XKB configuration
- * (keyboard)
- */
- extern unsigned XklGetNumGroups( void );
-
-/**
- * @return the array of group names for the current XKB configuration
- * (keyboard).
- * This array is static, should not be freed
- */
- extern const char **XklGetGroupNames( void );
-
-/**
- * @return the array of indicator names for the current XKB configuration
- * (keyboard).
- * This array is static, should not be freed
- */
- extern const char **XklGetIndicatorNames( void );
-
-/** @} */
-
-/**
- * @defgroup xkbgroup XKB group calculation and change
- * @{
- */
-
-/**
- * Calculates next group id. Does not change the state of anything.
- * @return next group id
- */
- extern int XklGetNextGroup( void );
-
-/**
- * Calculates prev group id. Does not change the state of anything.
- * @return prev group id
- */
- extern int XklGetPrevGroup( void );
-
-/**
- * @return saved group id of the current client.
- * Does not change the state of anything.
- */
- extern int XklGetRestoreGroup( void );
-
-/**
- * Locks the group. Can be used after XklGetXXXGroup functions
- * @param group is a group number for locking
- * @see XklGetNextGroup
- * @see XklGetPrevGroup
- * @see XklGetRestoreGroup
- */
- extern void XklLockGroup( int group );
-
-/** @} */
-
-/**
- * @defgroup callbacks Application callbacks support
- * @{
- */
-
-/**
- * Used for notifying application of the XKB configuration change.
- * @param userData is anything which can be stored into the pointer
- * @see XklRegisterConfigCallback
- */
- typedef void ( *XklConfigCallback ) ( void *userData );
-
-/**
- * Registers user callback. Only one callback can be registered at a time
- * @param fun is the function to call
- * @param userData is the data to pass
- * @see XklConfigCallback
- */
- extern int XklRegisterConfigCallback( XklConfigCallback fun,
- void *userData );
-
-/**
- * Used for notifying application of new window creation (actually,
- * registration).
- * @param win is a new window
- * @param parent is a new window's parent
- * @param userData is anything which can be stored into the pointer
- * @return the initial group id for the window (-1 to use the default value)
- * @see XklRegisterConfigCallback
- * @see XklSetDefaultGroup
- * @see XklGetDefaultGroup
- */
- typedef int ( *XklWinCallback ) ( Window win, Window parent,
- void *userData );
-
-/**
- * Registers user callback. Only one callback can be registered at a time
- * @param fun is the function to call
- * @param userData is the data to pass
- * @see XklWindowCallback
- */
- extern int XklRegisterWindowCallback( XklWinCallback fun, void *userData );
-
-/**
- * Used for notifying application of the window state change.
- * @param changeType is a mask of changes
- * @param group is a new group
- * @param restore is indicator of whether this state is restored from
- * saved state of set as new.
- * @param userData is anything which can be stored into the pointer
- * @see XklRegisterConfigCallback
- */
- typedef void ( *XklStateCallback ) ( XklStateChange changeType, int group,
- Bool restore, void *userData );
-
-/**
- * Registers user callback. Only one callback can be registered at a time
- * @param fun is the function to call
- * @param userData is the data to pass
- * @see XklStateCallback
- */
- extern int XklRegisterStateCallback( XklStateCallback fun, void *userData );
-
-/** @} */
+#include <glib-object.h>
-/**
- * @defgroup settings Settings for event processing
- * @{
- */
-
-/**
- * Sets the configuration parameter: group per application
- * @param isGlobal is a new parameter value
- */
- extern void XklSetGroupPerApp( Bool isGlobal );
-
-/**
- * @return the value of the parameter: group per application
- */
- extern Bool XklIsGroupPerApp( void );
-
-/**
- * Sets the configuration parameter: perform indicators handling
- * @param whetherHandle is a new parameter value
- */
- extern void XklSetIndicatorsHandling( Bool whetherHandle );
-
-/**
- * @return the value of the parameter: perform indicator handling
- */
- extern Bool XklGetIndicatorsHandling( void );
+#include <libxklavier/xkl_engine.h>
+#include <libxklavier/xkl_config_rec.h>
+#include <libxklavier/xkl_config_item.h>
+#include <libxklavier/xkl_config_registry.h>
-/**
- * Sets the secondary groups (one bit per group).
- * Secondary groups require explicit "allowance" for switching
- * @param mask is a new group mask
- * @see XklAllowOneSwitchToSecondaryGroup
- */
- extern void XklSetSecondaryGroupsMask( int mask );
-
-/**
- * @return the secondary group mask
- */
- extern int XklGetSecondaryGroupsMask( void );
-
-/**
- * Configures the default group set on window creation.
- * If -1, no default group is used
- * @param group the default group
- */
- extern void XklSetDefaultGroup( int group );
-
-/**
- * Returns the default group set on window creation
- * If -1, no default group is used
- * @return the default group
- */
- extern int XklGetDefaultGroup( void );
-
-/** @} */
-
-/**
- * @defgroup debugerr Debugging, error processing
- * @{
- */
+#ifdef __cplusplus
+extern "C" {
+#endif
/**
- * @return the text message (statically allocated) of the last error
+ * xkl_get_last_error:
+ *
+ * Returns: the text message (statically allocated) of the last error
*/
- extern const char *XklGetLastError( void );
+ extern const gchar *xkl_get_last_error(void);
/**
- * Output (optionally) some debug info
- * @param file is the name of the source file.
+ * _xkl_debug:
+ * @file: the name of the source file.
* Preprocessor symbol__FILE__ should be used here
- * @param function is a name of the function
+ * @function: name of the function
* Preprocessor symbol__func__ should be used here
- * @param level is a level of the message
- * @param format is a format (like in printf)
- * @see XklDebug
+ * @level: level of the message
+ * @format: is a format (like in printf)
+ *
+ * Output (optionally) some debug info
*/
- extern void _XklDebug( const char file[], const char function[], int level,
- const char format[], ... );
+ extern void _xkl_debug(const gchar file[], const gchar function[],
+ gint level, const gchar format[], ...);
/**
- * Custom log output method for _XklDebug. This appender is NOT called if the
- * level of the message is greater than currently set debug level.
- *
- * @param file is the name of the source file.
+ * XklLogAppender:
+ * @file: name of the source file.
* Preprocessor symbol__FILE__ should be used here
- * @param function is a name of the function
+ * @function: name of the function
* Preprocessor symbol__func__ should be used here
- * @param level is a level of the message
- * @param format is a format (like in printf)
- * @param args is the list of parameters
- * @see _XklDebug
- * @see XklSetDebugLevel
+ * @level: level of the message
+ * @format: format (like in printf)
+ * @args: list of parameters
+ *
+ * Custom log output method for _xkl_debug. This appender is NOT called if the
+ * level of the message is greater than currently set debug level.
*/
- typedef void ( *XklLogAppender ) ( const char file[], const char function[],
- int level, const char format[],
- va_list args );
+ typedef void (*XklLogAppender) (const gchar file[],
+ const gchar function[],
+ gint level,
+ const gchar format[],
+ va_list args);
/**
- * Default log output method. Sends everything to stdout.
- *
- * @param file is the name of the source file.
+ * xkl_default_log_appender:
+ * @file: name of the source file.
* Preprocessor symbol__FILE__ should be used here
- * @param function is a name of the function
+ * @function: name of the function
* Preprocessor symbol__func__ should be used here
- * @param level is a level of the message
- * @param format is a format (like in printf)
- * @param args is the list of parameters
+ * @level: level of the message
+ * @format: format (like in printf)
+ * @args: list of parameters
+ *
+ * Default log output method. Sends everything to stdout.
*/
- extern void XklDefaultLogAppender( const char file[], const char function[],
- int level, const char format[],
- va_list args );
+ extern void xkl_default_log_appender(const gchar file[],
+ const gchar function[],
+ gint level,
+ const gchar format[],
+ va_list args);
/**
+ * xkl_set_log_appender:
+ * @fun: new log appender
+ *
* Installs the custom log appender.function
- * @param fun is the new log appender
*/
- extern void XklSetLogAppender( XklLogAppender fun );
+ extern void xkl_set_log_appender(XklLogAppender fun);
/**
+ * xkl_set_debug_level:
+ * @level: new debug level
+ *
* Sets maximum debug level.
* Message of the level more than the one set here - will be ignored
- * @param level is a new debug level
*/
- extern void XklSetDebugLevel( int level );
+ extern void xkl_set_debug_level(gint level);
-/* Just to make doxygen happy - two block with/without @param format */
-#if defined(G_HAVE_GNUC_VARARGS)
+#ifdef G_HAVE_ISO_VARARGS
/**
+ * xkl_debug:
+ * @level: level of the message
+ *
* Output (optionally) some debug info
- * @param level is a level of the message
- * @param format is a format (like in printf)
- * @see _XklDebug
*/
-#else
+#define xkl_debug( level, ... ) \
+ _xkl_debug( __FILE__, __func__, level, __VA_ARGS__ )
+#elif defined(G_HAVE_GNUC_VARARGS)
/**
+ * xkl_debug:
+ * @level: level of the message
+ * @format: format (like in printf)
+ *
* Output (optionally) some debug info
- * @param level is a level of the message
- * @see _XklDebug
*/
-#endif
-#ifdef G_HAVE_ISO_VARARGS
-#define XklDebug( level, ... ) \
- _XklDebug( __FILE__, __func__, level, __VA_ARGS__ )
-#elif defined(G_HAVE_GNUC_VARARGS)
-#define XklDebug( level, format, args... ) \
- _XklDebug( __FILE__, __func__, level, format, ## args )
+#define xkl_debug( level, format, args... ) \
+ _xkl_debug( __FILE__, __func__, level, format, ## args )
#else
-#define XklDebug( level, ... ) \
- _XklDebug( __FILE__, __func__, level, __VA_ARGS__ )
+#define xkl_debug( level, ... ) \
+ _xkl_debug( __FILE__, __func__, level, __VA_ARGS__ )
#endif
-/** @} */
-
#ifdef __cplusplus
}
-#endif /* __cplusplus */
-
+#endif /* __cplusplus */
#endif
diff --git a/libxklavier/xklavier_config.c b/libxklavier/xklavier_config.c
index 6e8c0a4..84645ae 100644
--- a/libxklavier/xklavier_config.c
+++ b/libxklavier/xklavier_config.c
@@ -1,593 +1,721 @@
#include <errno.h>
-#include <string.h>
-#include <stdio.h>
#include <locale.h>
+#include <stdio.h>
+#include <string.h>
#include <sys/stat.h>
-#include <libxml/xpath.h>
-
#include "config.h"
#include "xklavier_private.h"
-typedef struct _XklConfigRegistry
-{
- xmlDocPtr doc;
- xmlXPathContextPtr xpathContext;
-}
-XklConfigRegistry;
-
-static XklConfigRegistry theRegistry;
-
-static xmlXPathCompExprPtr modelsXPath;
-static xmlXPathCompExprPtr layoutsXPath;
-static xmlXPathCompExprPtr optionGroupsXPath;
-
-#define _XklConfigRegistryIsInitialized() \
- ( theRegistry.xpathContext != NULL )
-
-static xmlChar *_XklNodeGetXmlLangAttr( xmlNodePtr nptr )
-{
- if( nptr->properties != NULL &&
- !strcmp( "lang", (char *)nptr->properties[0].name ) &&
- nptr->properties[0].ns != NULL &&
- !strcmp( "xml", (char *)nptr->properties[0].ns->prefix ) &&
- nptr->properties[0].children != NULL )
- return nptr->properties[0].children->content;
- else
- return NULL;
-}
-
-static Bool _XklReadConfigItem( xmlNodePtr iptr, XklConfigItemPtr pci )
-{
- xmlNodePtr nameElement, descElement = NULL, ntDescElement =
- NULL, nptr, ptr, shortDescElement = NULL, ntShortDescElement = NULL;
- int maxDescPriority = -1;
- int maxShortDescPriority = -1;
-
- *pci->name = 0;
- *pci->shortDescription = 0;
- *pci->description = 0;
- if( iptr->type != XML_ELEMENT_NODE )
- return False;
- ptr = iptr->children;
- while( ptr != NULL )
- {
- switch ( ptr->type )
- {
- case XML_ELEMENT_NODE:
- if( !strcmp( (char *)ptr->name, "configItem" ) )
- break;
- return False;
- case XML_TEXT_NODE:
- case XML_COMMENT_NODE:
- ptr = ptr->next;
- continue;
- default:
- return False;
- }
- break;
- }
- if( ptr == NULL )
- return False;
-
- nptr = ptr->children;
-
- if( nptr->type == XML_TEXT_NODE )
- nptr = nptr->next;
- nameElement = nptr;
- nptr = nptr->next;
-
- while( nptr != NULL )
- {
- if( nptr->type != XML_TEXT_NODE )
- {
- xmlChar *lang = _XklNodeGetXmlLangAttr( nptr );
-
- if( lang != NULL )
- {
- int priority = _XklGetLanguagePriority( (char *)lang );
- if( !strcmp( (char *)nptr->name, "description" ) && ( priority > maxDescPriority ) ) /* higher priority */
- {
- descElement = nptr;
- maxDescPriority = priority;
- } else if( !strcmp( (char *)nptr->name, "shortDescription" ) && ( priority > maxShortDescPriority ) ) /* higher priority */
- {
- shortDescElement = nptr;
- maxShortDescPriority = priority;
- }
- } else
- {
- if( !strcmp( (char *)nptr->name, "description" ) )
- ntDescElement = nptr;
- else if( !strcmp( (char *)nptr->name, "shortDescription" ) )
- ntShortDescElement = nptr;
- }
- }
- nptr = nptr->next;
- }
-
- /* if no language-specific description found - use the ones without lang */
- if( descElement == NULL )
- descElement = ntDescElement;
-
- if( shortDescElement == NULL )
- shortDescElement = ntShortDescElement;
-
- /**
- * Actually, here we should have some code to find the correct localized description...
- */
-
- if( nameElement != NULL && nameElement->children != NULL )
- strncat( pci->name, (char *)nameElement->children->content,
- XKL_MAX_CI_NAME_LENGTH - 1 );
-
- if( shortDescElement != NULL && shortDescElement->children != NULL )
- {
- char * lsd = _XklLocaleFromUtf8( (const char *)shortDescElement->children->content );
- strncat( pci->shortDescription,
- lsd,
- XKL_MAX_CI_SHORT_DESC_LENGTH - 1 );
- free( lsd );
- }
-
- if( descElement != NULL && descElement->children != NULL )
- {
- char * ld = _XklLocaleFromUtf8( (const char *)descElement->children->content );
- strncat( pci->description,
- ld,
- XKL_MAX_CI_DESC_LENGTH - 1 );
- free( ld );
- }
- return True;
-}
-
-static void _XklConfigEnumFromNodeSet( xmlNodeSetPtr nodes,
- ConfigItemProcessFunc func,
- void *userData )
+static GObjectClass *parent_class = NULL;
+
+static XklConfigRegistry *the_config = NULL;
+
+static xmlXPathCompExprPtr models_xpath;
+static xmlXPathCompExprPtr layouts_xpath;
+static xmlXPathCompExprPtr option_groups_xpath;
+
+enum {
+ PROP_0,
+ PROP_ENGINE,
+};
+
+#define xkl_config_registry_is_initialized(config) \
+ ( xkl_config_registry_priv(config,xpath_context) != NULL )
+
+static xmlChar *
+xkl_node_get_xml_lang_attr(xmlNodePtr nptr)
+{
+ if (nptr->properties != NULL &&
+ !g_ascii_strcasecmp("lang", (char *) nptr->properties[0].name)
+ && nptr->properties[0].ns != NULL
+ && !g_ascii_strcasecmp("xml",
+ (char *) nptr->properties[0].ns->prefix)
+ && nptr->properties[0].children != NULL)
+ return nptr->properties[0].children->content;
+ else
+ return NULL;
+}
+
+static gboolean
+xkl_read_config_item(xmlNodePtr iptr, XklConfigItem * item)
+{
+ xmlNodePtr name_element, nptr, ptr;
+ xmlNodePtr desc_element = NULL, short_desc_element = NULL;
+ xmlNodePtr nt_desc_element = NULL, nt_short_desc_element = NULL;
+
+ gint max_desc_priority = -1;
+ gint max_short_desc_priority = -1;
+
+ *item->name = 0;
+ *item->short_description = 0;
+ *item->description = 0;
+ if (iptr->type != XML_ELEMENT_NODE)
+ return FALSE;
+ ptr = iptr->children;
+ while (ptr != NULL) {
+ switch (ptr->type) {
+ case XML_ELEMENT_NODE:
+ if (!g_ascii_strcasecmp((char *) ptr->name,
+ "configItem"))
+ break;
+ return FALSE;
+ case XML_TEXT_NODE:
+ case XML_COMMENT_NODE:
+ ptr = ptr->next;
+ continue;
+ default:
+ return FALSE;
+ }
+ break;
+ }
+ if (ptr == NULL)
+ return FALSE;
+
+ nptr = ptr->children;
+
+ if (nptr->type == XML_TEXT_NODE)
+ nptr = nptr->next;
+ name_element = nptr;
+ nptr = nptr->next;
+
+ while (nptr != NULL) {
+ char *node_name = (char *) nptr->name;
+ if (nptr->type != XML_TEXT_NODE) {
+ xmlChar *lang = xkl_node_get_xml_lang_attr(nptr);
+
+ if (lang != NULL) {
+ gint priority =
+ xkl_get_language_priority((gchar *)
+ lang);
+
+ /*
+ * Find desc/shortdesc with highest priority
+ */
+ if (!g_ascii_strcasecmp(node_name,
+ "description") &&
+ (priority > max_desc_priority)) {
+ desc_element = nptr;
+ max_desc_priority = priority;
+ } else if (!g_ascii_strcasecmp(node_name,
+ "shortDescription")
+ && (priority >
+ max_short_desc_priority)) {
+ short_desc_element = nptr;
+ max_short_desc_priority = priority;
+ }
+ } else // no language specified!
+ {
+ if (!g_ascii_strcasecmp(node_name,
+ "description"))
+ nt_desc_element = nptr;
+ else if (!g_ascii_strcasecmp(node_name,
+ "shortDescription"))
+ nt_short_desc_element = nptr;
+ }
+ }
+ nptr = nptr->next;
+ }
+
+ /* if no language-specific description found - use the ones without lang */
+ if (desc_element == NULL)
+ desc_element = nt_desc_element;
+
+ if (short_desc_element == NULL)
+ short_desc_element = nt_short_desc_element;
+
+ /*
+ * Actually, here we should have some code to find
+ * the correct localized description...
+ */
+
+ if (name_element != NULL && name_element->children != NULL)
+ strncat(item->name,
+ (char *) name_element->children->content,
+ XKL_MAX_CI_NAME_LENGTH - 1);
+
+ if (short_desc_element != NULL &&
+ short_desc_element->children != NULL) {
+ gchar *lmsg = xkl_locale_from_utf8((const gchar *)
+ short_desc_element->
+ children->content);
+ strncat(item->short_description, lmsg,
+ XKL_MAX_CI_SHORT_DESC_LENGTH - 1);
+ g_free(lmsg);
+ }
+
+ if (desc_element != NULL && desc_element->children != NULL) {
+ gchar *lmsg =
+ xkl_locale_from_utf8((const gchar *) desc_element->
+ children->content);
+ strncat(item->description, lmsg,
+ XKL_MAX_CI_DESC_LENGTH - 1);
+ g_free(lmsg);
+ }
+ return TRUE;
+}
+
+static void
+xkl_config_registry_foreach_in_nodeset(XklConfigRegistry * config,
+ xmlNodeSetPtr nodes,
+ ConfigItemProcessFunc func,
+ gpointer data)
+{
+ gint i;
+ if (nodes != NULL) {
+ xmlNodePtr *pnode = nodes->nodeTab;
+ for (i = nodes->nodeNr; --i >= 0;) {
+ XklConfigItem ci;
+ if (xkl_read_config_item(*pnode, &ci))
+ func(&ci, data);
+
+ pnode++;
+ }
+ }
+}
+
+static void
+xkl_config_registry_foreach_in_xpath(XklConfigRegistry * config,
+ xmlXPathCompExprPtr xpath_comp_expr,
+ ConfigItemProcessFunc func,
+ gpointer data)
+{
+ xmlXPathObjectPtr xpath_obj;
+
+ if (!xkl_config_registry_is_initialized(config))
+ return;
+ xpath_obj = xmlXPathCompiledEval(xpath_comp_expr,
+ xkl_config_registry_priv(config,
+ xpath_context));
+ if (xpath_obj != NULL) {
+ xkl_config_registry_foreach_in_nodeset(config,
+ xpath_obj->
+ nodesetval, func,
+ data);
+ xmlXPathFreeObject(xpath_obj);
+ }
+}
+
+static void
+xkl_config_registry_foreach_in_xpath_with_param(XklConfigRegistry * config,
+ const gchar * format,
+ const gchar * value,
+ ConfigItemProcessFunc func,
+ gpointer data)
{
- int i;
- if( nodes != NULL )
- {
- xmlNodePtr *theNodePtr = nodes->nodeTab;
- for( i = nodes->nodeNr; --i >= 0; )
- {
- XklConfigItem ci;
- if( _XklReadConfigItem( *theNodePtr, &ci ) )
- func( &ci, userData );
+ char xpath_expr[1024];
+ xmlXPathObjectPtr xpath_obj;
- theNodePtr++;
- }
- }
+ if (!xkl_config_registry_is_initialized(config))
+ return;
+ snprintf(xpath_expr, sizeof xpath_expr, format, value);
+ xpath_obj = xmlXPathEval((unsigned char *) xpath_expr,
+ xkl_config_registry_priv(config,
+ xpath_context));
+ if (xpath_obj != NULL) {
+ xkl_config_registry_foreach_in_nodeset(config,
+ xpath_obj->
+ nodesetval, func,
+ data);
+ xmlXPathFreeObject(xpath_obj);
+ }
}
-static void _XklConfigEnumSimple( xmlXPathCompExprPtr xpathCompExpr,
- ConfigItemProcessFunc func, void *userData )
+static gboolean
+xkl_config_registry_find_object(XklConfigRegistry * config,
+ const gchar * format, const gchar * arg1,
+ XklConfigItem * pitem /* in/out */ ,
+ xmlNodePtr * pnode /* out */ )
{
- xmlXPathObjectPtr xpathObj;
+ xmlXPathObjectPtr xpath_obj;
+ xmlNodeSetPtr nodes;
+ gboolean rv = FALSE;
+ gchar xpath_expr[1024];
- if( !_XklConfigRegistryIsInitialized( ) )
- return;
- xpathObj = xmlXPathCompiledEval( xpathCompExpr, theRegistry.xpathContext );
- if( xpathObj != NULL )
- {
- _XklConfigEnumFromNodeSet( xpathObj->nodesetval, func, userData );
- xmlXPathFreeObject( xpathObj );
- }
-}
+ if (!xkl_config_registry_is_initialized(config))
+ return FALSE;
-static void _XklConfigEnumDirect( const char *format,
- const char *value,
- ConfigItemProcessFunc func, void *userData )
-{
- char xpathExpr[1024];
- xmlXPathObjectPtr xpathObj;
+ snprintf(xpath_expr, sizeof xpath_expr, format, arg1, pitem->name);
+ xpath_obj = xmlXPathEval((unsigned char *) xpath_expr,
+ xkl_config_registry_priv(config,
+ xpath_context));
+ if (xpath_obj == NULL)
+ return FALSE;
- if( !_XklConfigRegistryIsInitialized( ) )
- return;
- snprintf( xpathExpr, sizeof xpathExpr, format, value );
- xpathObj = xmlXPathEval( (unsigned char *)xpathExpr, theRegistry.xpathContext );
- if( xpathObj != NULL )
- {
- _XklConfigEnumFromNodeSet( xpathObj->nodesetval, func, userData );
- xmlXPathFreeObject( xpathObj );
- }
-}
-
-static Bool _XklConfigFindObject( const char *format,
- const char *arg1,
- XklConfigItemPtr ptr /* in/out */ ,
- xmlNodePtr * nodePtr /* out */ )
-{
- xmlXPathObjectPtr xpathObj;
- xmlNodeSetPtr nodes;
- Bool rv = False;
- char xpathExpr[1024];
-
- if( !_XklConfigRegistryIsInitialized( ) )
- return False;
-
- snprintf( xpathExpr, sizeof xpathExpr, format, arg1, ptr->name );
- xpathObj = xmlXPathEval( (unsigned char *)xpathExpr, theRegistry.xpathContext );
- if( xpathObj == NULL )
- return False;
-
- nodes = xpathObj->nodesetval;
- if( nodes != NULL && nodes->nodeTab != NULL )
- {
- rv = _XklReadConfigItem( *nodes->nodeTab, ptr );
- if( nodePtr != NULL )
- {
- *nodePtr = *nodes->nodeTab;
- }
- }
+ nodes = xpath_obj->nodesetval;
+ if (nodes != NULL && nodes->nodeTab != NULL) {
+ rv = xkl_read_config_item(*nodes->nodeTab, pitem);
+ if (pnode != NULL) {
+ *pnode = *nodes->nodeTab;
+ }
+ }
- xmlXPathFreeObject( xpathObj );
- return rv;
+ xmlXPathFreeObject(xpath_obj);
+ return rv;
}
-char *_XklConfigRecMergeLayouts( const XklConfigRecPtr data )
+gchar *
+xkl_config_rec_merge_layouts(const XklConfigRec * data)
{
- return _XklConfigRecMergeByComma( ( const char ** ) data->layouts,
- data->numLayouts );
+ return xkl_strings_concat_comma_separated(data->layouts);
}
-char *_XklConfigRecMergeVariants( const XklConfigRecPtr data )
+gchar *
+xkl_config_rec_merge_variants(const XklConfigRec * data)
{
- return _XklConfigRecMergeByComma( ( const char ** ) data->variants,
- data->numVariants );
+ return xkl_strings_concat_comma_separated(data->variants);
}
-char *_XklConfigRecMergeOptions( const XklConfigRecPtr data )
+gchar *
+xkl_config_rec_merge_options(const XklConfigRec * data)
{
- return _XklConfigRecMergeByComma( ( const char ** ) data->options,
- data->numOptions );
+ return xkl_strings_concat_comma_separated(data->options);
}
-char *_XklConfigRecMergeByComma( const char **array, const int arrayLength )
+gchar *
+xkl_strings_concat_comma_separated(gchar ** array)
{
- int len = 0;
- int i;
- char *merged;
- const char **theString;
-
- if( ( theString = array ) == NULL )
- return NULL;
-
- for( i = arrayLength; --i >= 0; theString++ )
- {
- if( *theString != NULL )
- len += strlen( *theString );
- len++;
- }
-
- if( len < 1 )
- return NULL;
-
- merged = ( char * ) malloc( len );
- merged[0] = '\0';
-
- theString = array;
- for( i = arrayLength; --i >= 0; theString++ )
- {
- if( *theString != NULL )
- strcat( merged, *theString );
- if( i != 0 )
- strcat( merged, "," );
- }
- return merged;
+ return g_strjoinv(",", array);
}
-void _XklConfigRecSplitLayouts( XklConfigRecPtr data, const char *merged )
+void
+xkl_config_rec_split_layouts(XklConfigRec * data, const gchar * merged)
{
- _XklConfigRecSplitByComma( &data->layouts, &data->numLayouts, merged );
+ xkl_strings_split_comma_separated(&data->layouts, merged);
}
-void _XklConfigRecSplitVariants( XklConfigRecPtr data, const char *merged )
+void
+xkl_config_rec_split_variants(XklConfigRec * data, const gchar * merged)
{
- _XklConfigRecSplitByComma( &data->variants, &data->numVariants, merged );
+ xkl_strings_split_comma_separated(&data->variants, merged);
}
-void _XklConfigRecSplitOptions( XklConfigRecPtr data, const char *merged )
+void
+xkl_config_rec_split_options(XklConfigRec * data, const gchar * merged)
{
- _XklConfigRecSplitByComma( &data->options, &data->numOptions, merged );
+ xkl_strings_split_comma_separated(&data->options, merged);
}
-void _XklConfigRecSplitByComma( char ***array,
- int *arraySize, const char *merged )
+void
+xkl_strings_split_comma_separated(gchar *** array, const gchar * merged)
{
- const char *pc = merged;
- char **ppc, *npc;
- *arraySize = 0;
- *array = NULL;
-
- if( merged == NULL || merged[0] == '\0' )
- return;
-
- /* first count the elements */
- while( ( npc = strchr( pc, ',' ) ) != NULL )
- {
- ( *arraySize )++;
- pc = npc + 1;
- }
- ( *arraySize )++;
-
- if( ( *arraySize ) != 0 )
- {
- int len;
- *array = ( char ** ) malloc( ( sizeof( char * ) ) * ( *arraySize ) );
-
- ppc = *array;
- pc = merged;
- while( ( npc = strchr( pc, ',' ) ) != NULL )
- {
- int len = npc - pc;
- /* *ppc = ( char * ) strndup( pc, len ); */
- *ppc = ( char * ) malloc( len + 1 );
- if ( *ppc != NULL )
- {
- strncpy( *ppc, pc, len );
- (*ppc)[len] = '\0';
- }
-
- ppc++;
- pc = npc + 1;
- }
-
- /* len = npc - pc; */
- len = strlen( pc );
- /* *ppc = ( char * ) strndup( pc, len ); */
- *ppc = ( char * ) malloc( len + 1 );
- if ( *ppc != NULL )
- strcpy( *ppc, pc );
- }
+ *array = g_strsplit(merged, ",", 0);
}
-char* _XklGetRulesSetName( const char defaultRuleset[] )
-{
- static char rulesSetName[1024] = "";
- if ( !rulesSetName[0] )
- {
- char* rf = NULL;
- if( !XklGetNamesProp( xklVTable->baseConfigAtom, &rf, NULL ) || ( rf == NULL ) )
- {
- strncpy( rulesSetName, defaultRuleset, sizeof rulesSetName );
- XklDebug( 100, "Using default rules set: [%s]\n", rulesSetName );
- return rulesSetName;
- }
- strncpy( rulesSetName, rf, sizeof rulesSetName );
- free( rf );
- }
- XklDebug( 100, "Rules set: [%s]\n", rulesSetName );
- return rulesSetName;
+gchar *
+xkl_engine_get_ruleset_name(XklEngine * engine,
+ const gchar default_ruleset[])
+{
+ static gchar rules_set_name[1024] = "";
+ if (!rules_set_name[0]) {
+ /* first call */
+ gchar *rf = NULL;
+ if (!xkl_config_rec_get_from_root_window_property
+ (NULL, xkl_engine_priv(engine, base_config_atom), &rf,
+ engine)
+ || (rf == NULL)) {
+ g_strlcpy(rules_set_name, default_ruleset,
+ sizeof rules_set_name);
+ xkl_debug(100, "Using default rules set: [%s]\n",
+ rules_set_name);
+ return rules_set_name;
+ }
+ g_strlcpy(rules_set_name, rf, sizeof rules_set_name);
+ g_free(rf);
+ }
+ xkl_debug(100, "Rules set: [%s]\n", rules_set_name);
+ return rules_set_name;
}
-void XklConfigInit( void )
+XklConfigRegistry *
+xkl_config_registry_get_instance(XklEngine * engine)
{
- xmlXPathInit( );
- modelsXPath = xmlXPathCompile( (unsigned char *)"/xkbConfigRegistry/modelList/model" );
- layoutsXPath = xmlXPathCompile( (unsigned char *)"/xkbConfigRegistry/layoutList/layout" );
- optionGroupsXPath =
- xmlXPathCompile( (unsigned char *)"/xkbConfigRegistry/optionList/group" );
- _XklI18NInit( );
+ if (the_config != NULL) {
+ g_object_ref(G_OBJECT(the_config));
+ return the_config;
+ }
+
+ if (!engine) {
+ xkl_debug(10,
+ "xkl_config_registry_get_instance : engine is NULL ?\n");
+ return NULL;
+ }
- _XklEnsureVTableInited();
- (*xklVTable->xklConfigInitHandler)();
+ the_config =
+ XKL_CONFIG_REGISTRY(g_object_new
+ (xkl_config_registry_get_type(), "engine",
+ engine, NULL));
+
+ return the_config;
}
-void XklConfigTerm( void )
+gboolean
+xkl_config_registry_load_from_file(XklConfigRegistry * config,
+ const gchar * file_name)
{
- if( modelsXPath != NULL )
- {
- xmlXPathFreeCompExpr( modelsXPath );
- modelsXPath = NULL;
- }
- if( layoutsXPath != NULL )
- {
- xmlXPathFreeCompExpr( layoutsXPath );
- layoutsXPath = NULL;
- }
- if( optionGroupsXPath != NULL )
- {
- xmlXPathFreeCompExpr( optionGroupsXPath );
- optionGroupsXPath = NULL;
- }
+ xkl_config_registry_priv(config, doc) = xmlParseFile(file_name);
+ if (xkl_config_registry_priv(config, doc) == NULL) {
+ xkl_config_registry_priv(config, xpath_context) = NULL;
+ xkl_last_error_message =
+ "Could not parse XKB configuration registry";
+ } else
+ xkl_config_registry_priv(config, xpath_context) =
+ xmlXPathNewContext(xkl_config_registry_priv
+ (config, doc));
+ return xkl_config_registry_is_initialized(config);
}
-Bool XklConfigLoadRegistryFromFile( const char * fileName )
+void
+xkl_config_registry_free(XklConfigRegistry * config)
{
- theRegistry.doc = xmlParseFile( fileName );
- if( theRegistry.doc == NULL )
- {
- theRegistry.xpathContext = NULL;
- _xklLastErrorMsg = "Could not parse XKB configuration registry";
- } else
- theRegistry.xpathContext = xmlXPathNewContext( theRegistry.doc );
- return _XklConfigRegistryIsInitialized( );
+ if (xkl_config_registry_is_initialized(config)) {
+ xmlXPathFreeContext(xkl_config_registry_priv
+ (config, xpath_context));
+ xmlFreeDoc(xkl_config_registry_priv(config, doc));
+ xkl_config_registry_priv(config, xpath_context) = NULL;
+ xkl_config_registry_priv(config, doc) = NULL;
+ }
}
-void XklConfigFreeRegistry( void )
-{
- if( _XklConfigRegistryIsInitialized( ) )
- {
- xmlXPathFreeContext( theRegistry.xpathContext );
- xmlFreeDoc( theRegistry.doc );
- theRegistry.xpathContext = NULL;
- theRegistry.doc = NULL;
+void
+xkl_config_registry_foreach_model(XklConfigRegistry * config,
+ ConfigItemProcessFunc func,
+ gpointer data)
+{
+ xkl_config_registry_foreach_in_xpath(config, models_xpath, func,
+ data);
+}
+
+void
+xkl_config_registry_foreach_layout(XklConfigRegistry * config,
+ ConfigItemProcessFunc func,
+ gpointer data)
+{
+ xkl_config_registry_foreach_in_xpath(config, layouts_xpath, func,
+ data);
+}
+
+void
+xkl_config_registry_foreach_layout_variant(XklConfigRegistry * config,
+ const gchar * layout_name,
+ ConfigItemProcessFunc func,
+ gpointer data)
+{
+ xkl_config_registry_foreach_in_xpath_with_param
+ (config,
+ "/xkbConfigRegistry/layoutList/layout/variantList/variant[../../configItem/name = '%s']",
+ layout_name, func, data);
+}
+
+void
+xkl_config_registry_foreach_option_group(XklConfigRegistry * config,
+ GroupProcessFunc func,
+ gpointer data)
+{
+ xmlXPathObjectPtr xpath_obj;
+ gint i;
+
+ if (!xkl_config_registry_is_initialized(config))
+ return;
+ xpath_obj =
+ xmlXPathCompiledEval(option_groups_xpath,
+ xkl_config_registry_priv(config,
+ xpath_context));
+ if (xpath_obj != NULL) {
+ xmlNodeSetPtr nodes = xpath_obj->nodesetval;
+ xmlNodePtr *pnode = nodes->nodeTab;
+ for (i = nodes->nodeNr; --i >= 0;) {
+ XklConfigItem ci;
+
+ if (xkl_read_config_item(*pnode, &ci)) {
+ gboolean allow_multisel = TRUE;
+ xmlChar *sallow_multisel =
+ xmlGetProp(*pnode,
+ (unsigned char *)
+ "allowMultipleSelection");
+ if (sallow_multisel != NULL) {
+ allow_multisel =
+ !g_ascii_strcasecmp("true",
+ (char *)
+ sallow_multisel);
+ xmlFree(sallow_multisel);
+ }
+
+ func(&ci, allow_multisel, data);
+ }
+
+ pnode++;
+ }
+ xmlXPathFreeObject(xpath_obj);
+ }
+}
+
+void
+xkl_config_registry_foreach_option(XklConfigRegistry * config,
+ const gchar * option_group_name,
+ ConfigItemProcessFunc func,
+ gpointer data)
+{
+ xkl_config_registry_foreach_in_xpath_with_param
+ (config,
+ "/xkbConfigRegistry/optionList/group/option[../configItem/name = '%s']",
+ option_group_name, func, data);
+}
+
+gboolean
+xkl_config_registry_find_model(XklConfigRegistry * config,
+ XklConfigItem * pitem /* in/out */ )
+{
+ return
+ xkl_config_registry_find_object
+ (config,
+ "/xkbConfigRegistry/modelList/model[configItem/name = '%s%s']",
+ "", pitem, NULL);
+}
+
+gboolean
+xkl_config_registry_find_layout(XklConfigRegistry * config,
+ XklConfigItem * pitem /* in/out */ )
+{
+ return
+ xkl_config_registry_find_object
+ (config,
+ "/xkbConfigRegistry/layoutList/layout[configItem/name = '%s%s']",
+ "", pitem, NULL);
+}
+
+gboolean
+xkl_config_registry_find_variant(XklConfigRegistry * config,
+ const char *layout_name,
+ XklConfigItem * pitem /* in/out */ )
+{
+ return
+ xkl_config_registry_find_object
+ (config,
+ "/xkbConfigRegistry/layoutList/layout/variantList/variant"
+ "[../../configItem/name = '%s' and configItem/name = '%s']",
+ layout_name, pitem, NULL);
+}
+
+gboolean
+xkl_config_registry_find_option_group(XklConfigRegistry * config,
+ XklConfigItem * pitem /* in/out */ ,
+ gboolean *
+ allow_multiple_selection /* out */ )
+{
+ xmlNodePtr node;
+ gboolean rv = xkl_config_registry_find_object(config,
+ "/xkbConfigRegistry/optionList/group[configItem/name = '%s%s']",
+ "",
+ pitem, &node);
+
+ if (rv && allow_multiple_selection != NULL) {
+ xmlChar *val = xmlGetProp(node,
+ (unsigned char *)
+ "allowMultipleSelection");
+ *allow_multiple_selection = FALSE;
+ if (val != NULL) {
+ *allow_multiple_selection =
+ !g_ascii_strcasecmp("true", (char *) val);
+ xmlFree(val);
+ }
+ }
+ return rv;
+}
+
+gboolean
+xkl_config_registry_find_option(XklConfigRegistry * config,
+ const char *option_group_name,
+ XklConfigItem * pitem /* in/out */ )
+{
+ return
+ xkl_config_registry_find_object
+ (config, "/xkbConfigRegistry/optionList/group/option"
+ "[../configItem/name = '%s' and configItem/name = '%s']",
+ option_group_name, pitem, NULL);
+}
+
+/*
+ * Calling through vtable
+ */
+gboolean
+xkl_config_rec_activate(const XklConfigRec * data, XklEngine * engine)
+{
+ xkl_engine_ensure_vtable_inited(engine);
+ return xkl_engine_vcall(engine, activate_config_rec) (engine,
+ data);
+}
+
+gboolean
+xkl_config_registry_load(XklConfigRegistry * config)
+{
+ XklEngine *engine = xkl_config_registry_get_engine(config);
+ xkl_engine_ensure_vtable_inited(engine);
+ return xkl_engine_vcall(engine, load_config_registry) (config);
+}
+
+gboolean
+xkl_config_rec_write_to_file(XklEngine * engine, const gchar * file_name,
+ const XklConfigRec * data,
+ const gboolean binary)
+{
+ if ((!binary &&
+ !(xkl_engine_priv(engine, features) &
+ XKLF_CAN_OUTPUT_CONFIG_AS_ASCII))
+ || (binary
+ && !(xkl_engine_priv(engine, features) &
+ XKLF_CAN_OUTPUT_CONFIG_AS_BINARY))) {
+ xkl_last_error_message =
+ "Function not supported at backend";
+ return FALSE;
+ }
+ xkl_engine_ensure_vtable_inited(engine);
+ return xkl_engine_vcall(engine, write_config_rec_to_file) (engine,
+ file_name,
+ data,
+ binary);
+}
+
+void
+xkl_config_rec_dump(FILE * file, XklConfigRec * data)
+{
+ int j;
+ fprintf(file, " model: [%s]\n", data->model);
+
+ fprintf(file, " layouts:\n");
+#define OUTPUT_ARRZ(arrz) \
+ { \
+ fprintf( file, " " #arrz ":\n" ); \
+ gchar **p = data->arrz; \
+ if ( p != NULL ) \
+ for( j = 0; *p != NULL; ) \
+ fprintf( file, " %d: [%s]\n", j++, *p++ ); \
}
-}
+ OUTPUT_ARRZ(layouts);
+ OUTPUT_ARRZ(variants);
+ OUTPUT_ARRZ(options);
-void XklConfigEnumModels( ConfigItemProcessFunc func, void *userData )
-{
- _XklConfigEnumSimple( modelsXPath, func, userData );
}
-void XklConfigEnumLayouts( ConfigItemProcessFunc func, void *userData )
-{
- _XklConfigEnumSimple( layoutsXPath, func, userData );
-}
+G_DEFINE_TYPE(XklConfigRegistry, xkl_config_registry, G_TYPE_OBJECT)
-void XklConfigEnumLayoutVariants( const char *layoutName,
- ConfigItemProcessFunc func, void *userData )
+static GObject *
+xkl_config_registry_constructor(GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *
+ construct_properties)
{
- _XklConfigEnumDirect
- ( "/xkbConfigRegistry/layoutList/layout/variantList/variant[../../configItem/name = '%s']",
- layoutName, func, userData );
-}
+ GObject *obj;
-void XklConfigEnumOptionGroups( GroupProcessFunc func, void *userData )
-{
- xmlXPathObjectPtr xpathObj;
- int i;
+ {
+ /* Invoke parent constructor. */
+ XklConfigRegistryClass *klass;
+ klass =
+ XKL_CONFIG_REGISTRY_CLASS(g_type_class_peek
+ (XKL_TYPE_CONFIG_REGISTRY));
+ obj =
+ parent_class->constructor(type, n_construct_properties,
+ construct_properties);
+ }
- if( !_XklConfigRegistryIsInitialized( ) )
- return;
- xpathObj =
- xmlXPathCompiledEval( optionGroupsXPath, theRegistry.xpathContext );
- if( xpathObj != NULL )
- {
- xmlNodeSetPtr nodes = xpathObj->nodesetval;
- xmlNodePtr *theNodePtr = nodes->nodeTab;
- for( i = nodes->nodeNr; --i >= 0; )
- {
- XklConfigItem ci;
+ XklConfigRegistry *config = XKL_CONFIG_REGISTRY(obj);
- if( _XklReadConfigItem( *theNodePtr, &ci ) )
- {
- Bool allowMC = True;
- xmlChar *allowMCS =
- xmlGetProp( *theNodePtr, (unsigned char *)"allowMultipleSelection" );
- if( allowMCS != NULL )
- {
- allowMC = strcmp( "false", (char *)allowMCS );
- xmlFree( allowMCS );
- }
+ XklEngine *engine =
+ XKL_ENGINE(g_value_peek_pointer(construct_properties[0].
+ value));
+ xkl_config_registry_get_engine(config) = engine;
- func( &ci, allowMC, userData );
- }
+ xkl_engine_ensure_vtable_inited(engine);
+ xkl_engine_vcall(engine, init_config_registry) (config);
- theNodePtr++;
- }
- xmlXPathFreeObject( xpathObj );
- }
+ return obj;
}
-void XklConfigEnumOptions( const char *optionGroupName,
- ConfigItemProcessFunc func, void *userData )
+static void
+xkl_config_registry_init(XklConfigRegistry * config)
{
- _XklConfigEnumDirect
- ( "/xkbConfigRegistry/optionList/group/option[../configItem/name = '%s']",
- optionGroupName, func, userData );
+ config->priv = g_new0(XklConfigRegistryPrivate, 1);
}
-Bool XklConfigFindModel( XklConfigItemPtr ptr /* in/out */ )
+static void
+xkl_config_registry_set_property(GObject * object,
+ guint property_id,
+ const GValue * value, GParamSpec * pspec)
{
- return
- _XklConfigFindObject
- ( "/xkbConfigRegistry/modelList/model[configItem/name = '%s%s']", "",
- ptr, NULL );
}
-Bool XklConfigFindLayout( XklConfigItemPtr ptr /* in/out */ )
+static void
+xkl_config_registry_get_property(GObject * object,
+ guint property_id,
+ GValue * value, GParamSpec * pspec)
{
- return
- _XklConfigFindObject
- ( "/xkbConfigRegistry/layoutList/layout[configItem/name = '%s%s']", "",
- ptr, NULL );
-}
+ XklConfigRegistry *config = XKL_CONFIG_REGISTRY(object);
+
+ switch (property_id) {
+ case PROP_ENGINE:
+ g_value_set_pointer(value,
+ xkl_config_registry_get_engine
+ (config));
+ break;
+ }
-Bool XklConfigFindVariant( const char *layoutName,
- XklConfigItemPtr ptr /* in/out */ )
-{
- return
- _XklConfigFindObject
- ( "/xkbConfigRegistry/layoutList/layout/variantList/variant"
- "[../../configItem/name = '%s' and configItem/name = '%s']",
- layoutName, ptr, NULL );
}
-Bool XklConfigFindOptionGroup( XklConfigItemPtr ptr /* in/out */ ,
- Bool * allowMultipleSelection /* out */ )
+static void
+xkl_config_registry_finalize(GObject * obj)
{
- xmlNodePtr node;
- Bool rv =
- _XklConfigFindObject
- ( "/xkbConfigRegistry/optionList/group[configItem/name = '%s%s']", "",
- ptr, &node );
+ XklConfigRegistry *config = (XklConfigRegistry *) obj;
- if( rv && allowMultipleSelection != NULL )
- {
- xmlChar *val = xmlGetProp( node, (unsigned char *)"allowMultipleSelection" );
- *allowMultipleSelection = False;
- if( val != NULL )
- {
- *allowMultipleSelection = !strcmp( (char *)val, "true" );
- xmlFree( val );
- }
- }
- return rv;
-}
+ if (models_xpath != NULL) {
+ xmlXPathFreeCompExpr(models_xpath);
+ models_xpath = NULL;
+ }
+ if (layouts_xpath != NULL) {
+ xmlXPathFreeCompExpr(layouts_xpath);
+ layouts_xpath = NULL;
+ }
+ if (option_groups_xpath != NULL) {
+ xmlXPathFreeCompExpr(option_groups_xpath);
+ option_groups_xpath = NULL;
+ }
-Bool XklConfigFindOption( const char *optionGroupName,
- XklConfigItemPtr ptr /* in/out */ )
-{
- return
- _XklConfigFindObject
- ( "/xkbConfigRegistry/optionList/group/option"
- "[../configItem/name = '%s' and configItem/name = '%s']",
- optionGroupName, ptr, NULL );
-}
+ g_free(config->priv);
-/**
- * Calling through vtable
- */
-Bool XklConfigActivate( const XklConfigRecPtr data )
-{
- _XklEnsureVTableInited();
- return (*xklVTable->xklConfigActivateHandler)( data );
+ G_OBJECT_CLASS(parent_class)->finalize(obj);
}
-Bool XklConfigLoadRegistry( void )
+static void
+xkl_config_registry_class_init(XklConfigRegistryClass * klass)
{
- _XklEnsureVTableInited();
- return (*xklVTable->xklConfigLoadRegistryHandler)();
-}
+ GObjectClass *object_class;
-Bool XklConfigWriteFile( const char *fileName,
- const XklConfigRecPtr data,
- const Bool binary )
-{
- if( ( !binary &&
- !( xklVTable->features & XKLF_CAN_OUTPUT_CONFIG_AS_ASCII ) ) ||
- ( binary &&
- !( xklVTable->features & XKLF_CAN_OUTPUT_CONFIG_AS_BINARY ) ) )
- {
- _xklLastErrorMsg = "Function not supported at backend";
- return False;
- }
- _XklEnsureVTableInited();
- return (*xklVTable->xklConfigWriteFileHandler)( fileName, data, binary );
-}
+ object_class = (GObjectClass *) klass;
+ parent_class = g_type_class_peek_parent(object_class);
+ object_class->constructor = xkl_config_registry_constructor;
+ object_class->finalize = xkl_config_registry_finalize;
+ object_class->set_property = xkl_config_registry_set_property;
+ object_class->get_property = xkl_config_registry_get_property;
-void XklConfigDump( FILE* file,
- XklConfigRecPtr data )
-{
- int i,j;
- char**p;
- fprintf( file, " model: [%s]\n", data->model );
+ GParamSpec *engine_param_spec = g_param_spec_object("engine",
+ "Engine",
+ "XklEngine",
+ XKL_TYPE_ENGINE,
+ G_PARAM_CONSTRUCT_ONLY
+ |
+ G_PARAM_READWRITE);
- fprintf( file, " layouts(%d):\n", data->numLayouts );
- p = data->layouts;
- for( i = data->numLayouts, j = 0; --i >= 0; )
- fprintf( file, " %d: [%s]\n", j++, *p++ );
+ g_object_class_install_property(object_class,
+ PROP_ENGINE, engine_param_spec);
- fprintf( file, " variants(%d):\n", data->numVariants );
- p = data->variants;
- for( i = data->numVariants, j = 0; --i >= 0; )
- fprintf( file, " %d: [%s]\n", j++, *p++ );
+ /* static stuff initialized */
- fprintf( file, " options(%d):\n", data->numOptions );
- p = data->options;
- for( i = data->numOptions, j = 0; --i >= 0; )
- fprintf( file, " %d: [%s]\n", j++, *p++ );
+ xmlXPathInit();
+ models_xpath = xmlXPathCompile((unsigned char *)
+ "/xkbConfigRegistry/modelList/model");
+ layouts_xpath = xmlXPathCompile((unsigned char *)
+ "/xkbConfigRegistry/layoutList/layout");
+ option_groups_xpath = xmlXPathCompile((unsigned char *)
+ "/xkbConfigRegistry/optionList/group");
+ xkl_i18n_init();
}
diff --git a/libxklavier/xklavier_config.h b/libxklavier/xklavier_config.h
deleted file mode 100644
index 264f760..0000000
--- a/libxklavier/xklavier_config.h
+++ /dev/null
@@ -1,376 +0,0 @@
-/**
- * @file xklavier_config.h
- */
-
-#ifndef __XKLAVIER_CONFIG_H__
-#define __XKLAVIER_CONFIG_H__
-
-#include <libxklavier/xklavier.h>
-
-/**
- * Maximum name length, including '\'0' character
- */
-#define XKL_MAX_CI_NAME_LENGTH 32
-
-/**
- * Maximum short description length, including '\\0' character.
- * Important: this length is in bytes, so for unicode (UTF-8 encoding in
- * XML file) the actual maximum length can be smaller.
- */
-#define XKL_MAX_CI_SHORT_DESC_LENGTH 10
-
-/**
- * Maximum description length, including '\\0' character.
- * Important: this length is in bytes, so for unicode (UTF-8 encoding in
- * XML file) the actual maximum length can be smaller.
- */
-#define XKL_MAX_CI_DESC_LENGTH 192
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-/**
- * The configuration item. Corresponds to XML element "configItem".
- */
- typedef struct _XklConfigItem
- {
-/**
- * The configuration item name. Corresponds to XML element "name".
- */
- char name[XKL_MAX_CI_NAME_LENGTH];
-
-/**
- * The configuration item short description. Corresponds to XML element "shortDescription".
- */
- char shortDescription[XKL_MAX_CI_DESC_LENGTH];
-
-/**
- * The configuration item description. Corresponds to XML element "description".
- */
- char description[XKL_MAX_CI_DESC_LENGTH];
- }
- XklConfigItem, *XklConfigItemPtr;
-
-/**
- * Basic configuration params
- */
- typedef struct _XklConfigRec
- {
-/**
- * The keyboard model
- */
- char *model;
-/**
- * The number of keyboard layouts
- */
- int numLayouts;
-/**
- * The array of keyboard layouts
- */
- char **layouts;
-/**
- * The number of keyboard layout variants
- */
- int numVariants;
-/**
- * The array of keyboard layout variants (if any)
- */
- char **variants;
-/**
- * The number of keyboard layout options
- */
- int numOptions;
-/**
- * The array of keyboard layout options
- */
- char **options;
- }
- XklConfigRec, *XklConfigRecPtr;
-/**
- * @defgroup xklconfiginitterm XKB configuration handling initialization and termination
- * @{
- */
-
-/**
- * Initializes XML configuration-related structures
- */
- extern void XklConfigInit( void );
-
-/**
- * Cleans XML configuration-related structures
- */
- extern void XklConfigTerm( void );
-
-/**
- * Loads XML configuration registry
- * @param fileName file name to load
- * @return true on success
- */
- extern Bool XklConfigLoadRegistryFromFile( const char* fileName );
-
-/**
- * Loads XML configuration registry
- * @return true on success
- */
- extern Bool XklConfigLoadRegistry( void );
-
-/**
- * Frees XML configuration registry
- */
- extern void XklConfigFreeRegistry( void );
-/** @} */
-
-/**
- * @defgroup enum XKB configuration elements enumeration functions
- * @{
- */
-
-/**
- * Callback type used for enumerating keyboard models, layouts, variants, options
- * @param configItem is the item from registry
- * @param userData is anything which can be stored into the pointer
- */
- typedef void ( *ConfigItemProcessFunc ) ( const XklConfigItemPtr configItem,
- void *userData );
-
-/**
- * Callback type used for enumerating keyboard option groups
- * @param configItem is the item from registry
- * @param allowMultipleSelection is a flag whether this group allows multiple selection
- * @param userData is anything which can be stored into the pointer
- */
- typedef void ( *GroupProcessFunc ) ( const XklConfigItemPtr configItem,
- Bool allowMultipleSelection,
- void *userData );
-/**
- * Enumerates keyboard models from the XML configuration registry
- * @param func is a callback to call for every model
- * @param userData is anything which can be stored into the pointer
- */
- extern void XklConfigEnumModels( ConfigItemProcessFunc func,
- void *userData );
-
-/**
- * Enumerates keyboard layouts from the XML configuration registry
- * @param func is a callback to call for every layout
- * @param userData is anything which can be stored into the pointer
- */
- extern void XklConfigEnumLayouts( ConfigItemProcessFunc func,
- void *userData );
-
-/**
- * Enumerates keyboard layout variants from the XML configuration registry
- * @param layoutName is the layout name for which variants will be listed
- * @param func is a callback to call for every layout variant
- * @param userData is anything which can be stored into the pointer
- */
- extern void XklConfigEnumLayoutVariants( const char *layoutName,
- ConfigItemProcessFunc func,
- void *userData );
-
-/**
- * Enumerates keyboard option groups from the XML configuration registry
- * @param func is a callback to call for every option group
- * @param userData is anything which can be stored into the pointer
- */
- extern void XklConfigEnumOptionGroups( GroupProcessFunc func,
- void *userData );
-
-/**
- * Enumerates keyboard options from the XML configuration registry
- * @param optionGroupName is the option group name for which variants
- * will be listed
- * @param func is a callback to call for every option
- * @param userData is anything which can be stored into the pointer
- */
- extern void XklConfigEnumOptions( const char *optionGroupName,
- ConfigItemProcessFunc func,
- void *userData );
-
-/** @} */
-
-/**
- * @defgroup lookup XKB configuration element lookup functions
- * @{
- */
-
-/**
- * Loads a keyboard model information from the XML configuration registry.
- * @param ptr is a pointer to a XklConfigItem containing the name of the
- * keyboard model. On successfull return, the descriptions are filled.
- * @return True if appropriate element was found and loaded
- */
- extern Bool XklConfigFindModel( XklConfigItemPtr ptr );
-
-/**
- * Loads a keyboard layout information from the XML configuration registry.
- * @param ptr is a pointer to a XklConfigItem containing the name of the
- * keyboard layout. On successfull return, the descriptions are filled.
- * @return True if appropriate element was found and loaded
- */
- extern Bool XklConfigFindLayout( XklConfigItemPtr ptr );
-
-/**
- * Loads a keyboard layout variant information from the XML configuration
- * registry.
- * @param layoutName is a name of the parent layout
- * @param ptr is a pointer to a XklConfigItem containing the name of the
- * keyboard layout variant. On successfull return, the descriptions are filled.
- * @return True if appropriate element was found and loaded
- */
- extern Bool XklConfigFindVariant( const char *layoutName,
- XklConfigItemPtr ptr );
-
-/**
- * Loads a keyboard option group information from the XML configuration
- * registry.
- * @param ptr is a pointer to a XklConfigItem containing the name of the
- * keyboard option group. On successfull return, the descriptions are filled.
- * @param allowMultipleSelection is a pointer to some Bool variable to fill
- * the corresponding attribute of XML element "group".
- * @return True if appropriate element was found and loaded
- */
- extern Bool XklConfigFindOptionGroup( XklConfigItemPtr ptr,
- Bool * allowMultipleSelection );
-
-/**
- * Loads a keyboard option information from the XML configuration
- * registry.
- * @param optionGroupName is a name of the option group
- * @param ptr is a pointer to a XklConfigItem containing the name of the
- * keyboard option. On successfull return, the descriptions are filled.
- * @return True if appropriate element was found and loaded
- */
- extern Bool XklConfigFindOption( const char *optionGroupName,
- XklConfigItemPtr ptr );
-/** @} */
-
-/**
- * @defgroup activation XKB configuration activation
- * @{
- */
-
-/**
- * Activates some XKB configuration
- * @param data is a valid XKB configuration
- * description. Can be NULL
- * @return True on success
- * @see XklSetKeyAsSwitcher
- * At the moment, accepts only _ONE_ layout. Later probably I'll improve this..
- */
- extern Bool XklConfigActivate( const XklConfigRecPtr data );
-
-/**
- * Loads the current XKB configuration (from X server)
- * @param data is a buffer for XKB configuration
- * @return True on success
- */
- extern Bool XklConfigGetFromServer( XklConfigRecPtr data );
-
-/**
- * Loads the current XKB configuration (from backup)
- * @param data is a buffer for XKB configuration
- * @return True on success
- * @see XklBackupNamesProp
- */
- extern Bool XklConfigGetFromBackup( XklConfigRecPtr data );
-
-/**
- * Writes some XKB configuration into XKM/XKB file
- * @param fileName is a name of the file to create
- * @param data is a valid XKB configuration
- * description. Can be NULL
- * @param binary is a flag indicating whether the output file should be binary
- * @return True on success
- */
- extern Bool XklConfigWriteFile( const char *fileName,
- const XklConfigRecPtr data,
- const Bool binary );
-
-/** @} */
-
-/**
- * @defgroup props Saving and restoring XKB configuration into X root window properties
- * Generalizes XkbRF_GetNamesProp and XkbRF_SetNamesProp.
- * @{
- */
-
-/**
- * Gets the XKB configuration from any root window property
- * @param rulesAtomName is an atom name of the root window property to read
- * @param rulesFileOut is a pointer to hold the file name
- * @param configOut is a buffer to hold the result -
- * all records are allocated using standard malloc
- * @return True on success
- */
- extern Bool XklGetNamesProp( Atom rulesAtomName,
- char **rulesFileOut,
- XklConfigRecPtr configOut );
-
-/**
- * Saves the XKB configuration into any root window property
- * @param rulesAtomName is an atom name of the root window property to write
- * @param rulesFile is a rules file name
- * @param config is a configuration to save
- * @return True on success
- */
- extern Bool XklSetNamesProp( Atom rulesAtomName,
- char *rulesFile, XklConfigRecPtr config );
-
-/**
- * Backups current XKB configuration into some property -
- * if this property is not defined yet.
- * @return True on success
- */
- extern Bool XklBackupNamesProp( );
-
-/**
- * Restores XKB from the property saved by XklBackupNamesProp
- * @return True on success
- * @see XklBackupNamesProp
- */
- extern Bool XklRestoreNamesProp( );
-
-/** @} */
-
-/**
- * @defgroup xklconfig XklConfigRec management utilities
- * Little utilities for managing XklConfigRec.
- * @{
- */
-
-/**
- * Initializes the record (actually, fills it with 0-s)
- * @param data is a record to initialize
- */
- extern void XklConfigRecInit( XklConfigRecPtr data );
-
-/**
- * Resets the record (equal to Destroy and Init)
- * @param data is a record to reset
- */
- extern void XklConfigRecReset( XklConfigRecPtr data );
-
-/**
- * Cleans the record (frees all the non-null members)
- * @param data is a record to clean
- */
- extern void XklConfigRecDestroy( XklConfigRecPtr data );
-
-/**
- * Compares the records
- * @param data1 is a record to compare
- * @param data2 is another record
- * @return True if records are same
- */
- extern Bool XklConfigRecEquals( XklConfigRecPtr data1, XklConfigRecPtr data2 );
-
-/** @} */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif
diff --git a/libxklavier/xklavier_config_i18n.c b/libxklavier/xklavier_config_i18n.c
index 9a91577..4ff9a70 100644
--- a/libxklavier/xklavier_config_i18n.c
+++ b/libxklavier/xklavier_config_i18n.c
@@ -1,6 +1,6 @@
+#include <iconv.h>
#include <stdlib.h>
#include <string.h>
-#include <iconv.h>
#include "config.h"
@@ -16,218 +16,220 @@
#define MAX_LOCALE_LEN 128
-static char localeSubStrings[3][MAX_LOCALE_LEN];
+static gchar locale_sub_strings[3][MAX_LOCALE_LEN];
/*
* some bad guys create LC_ALL=LC_CTYPE=ru_RU.UTF-8;LC_NUMERIC=C;LC_TIME=ru_RU.UTF-8;LC_COLLATE=ru_RU.UTF-8;LC_MONETARY=ru_RU.UTF-8;LC_MESSAGES=ru_RU.UTF-8;LC_PAPER=ru_RU.UTF-8;LC_NAME=ru_RU.UTF-8;LC_ADDRESS=ru_RU.UTF-8;LC_TELEPHONE=ru_RU.UTF-8;LC_MEASUREMENT=ru_RU.UTF-8;LC_IDENTIFICATION=ru_RU.UTF-8
*/
-static const char *_XklParseLC_ALL2LC_MESSAGES( const char *lcAll )
+static const gchar *
+xkl_parse_LC_ALL_to_LC_MESSAGES(const gchar * lc_all)
{
- const char *lcMsgPos = strstr( lcAll, "LC_MESSAGES=" );
- const char *lcMsgEnd;
- size_t len;
- static char buf[128];
- if( lcMsgPos == NULL )
- return lcAll;
- lcMsgPos += 12;
- lcMsgEnd = strchr( lcMsgPos, ';' );
- if( lcMsgEnd == NULL ) /* LC_MESSAGES is the last piece of LC_ALL */
- {
- return lcMsgPos; /* safe to return! */
- }
- len = lcMsgEnd - lcMsgPos;
- if( len > sizeof( buf ) )
- len = sizeof( buf );
- strncpy( buf, lcMsgPos, len );
- buf[sizeof( buf ) - 1] = '\0';
- return buf;
+ const gchar *lc_message_pos =
+ g_strstr_len(lc_all, -1, "LC_MESSAGES=");
+ const gchar *lc_message_end;
+ size_t len;
+ static gchar buf[128];
+ if (lc_message_pos == NULL)
+ return lc_all;
+ lc_message_pos += 12;
+ lc_message_end = g_strstr_len(lc_message_pos, -1, ";");
+ if (lc_message_end == NULL) { /* LC_MESSAGES is the last piece of LC_ALL */
+ return lc_message_pos; /* safe to return! */
+ }
+ len = lc_message_end - lc_message_pos;
+ if (len > sizeof(buf))
+ len = sizeof(buf);
+ g_strlcpy(buf, lc_message_pos, len);
+ return buf;
}
/* Taken from gnome-vfs */
-static Bool _XklGetCharset( const char **a )
+static gboolean
+xkl_get_charset(const gchar ** a)
{
- static const char *charset = NULL;
+ static const gchar *charset = NULL;
- if( charset == NULL )
- {
- charset = getenv( "CHARSET" );
+ if (charset == NULL) {
+ charset = g_getenv("CHARSET");
- if( charset == NULL || charset[0] == '\0' )
- {
-/* taken from gnome-vfs */
+ if (charset == NULL || charset[0] == '\0') {
#ifdef HAVE_LANGINFO_CODESET
- charset = nl_langinfo( CODESET );
- if( charset == NULL || charset[0] == '\0' )
- {
+ charset = nl_langinfo(CODESET);
+ if (charset == NULL || charset[0] == '\0') {
#endif
#ifdef HAVE_SETLOCALE
- charset = setlocale( LC_CTYPE, NULL );
- if( charset == NULL || charset[0] == '\0' )
- {
+ charset = setlocale(LC_CTYPE, NULL);
+ if (charset == NULL || charset[0] == '\0') {
#endif
- charset = getenv( "LC_ALL" );
- if( charset == NULL || charset[0] == '\0' )
- {
- charset = getenv( "LC_CTYPE" );
- if( charset == NULL || charset[0] == '\0' )
- charset = getenv( "LANG" );
- }
+ charset = getenv("LC_ALL");
+ if (charset == NULL
+ || charset[0] == '\0') {
+ charset =
+ getenv("LC_CTYPE");
+ if (charset == NULL
+ || charset[0] == '\0')
+ charset =
+ getenv("LANG");
+ }
#ifdef HAVE_SETLOCALE
- } else
- {
- XklDebug( 150, "Using charset from setlocale: [%s]\n", charset );
- }
+ } else {
+ xkl_debug(150,
+ "Using charset from setlocale: [%s]\n",
+ charset);
+ }
#endif
#ifdef HAVE_LANGINFO_CODESET
- } else
- {
- XklDebug( 150, "Using charset from nl_langinfo: [%s]\n", charset );
- }
+ } else {
+ xkl_debug(150,
+ "Using charset from nl_langinfo: [%s]\n",
+ charset);
+ }
#endif
- }
- }
-
- if( charset != NULL && *charset != '\0' )
- {
- *a = charset;
- return ( charset != NULL && strstr( charset, "UTF-8" ) != NULL );
- }
- /* Assume this for compatibility at present. */
- *a = "US-ASCII";
- XklDebug( 150, "Using charset fallback: [%s]\n", *a );
-
- return False;
+ }
+ }
+
+ if (charset != NULL && *charset != '\0') {
+ *a = charset;
+ return (charset != NULL
+ && g_strstr_len(charset, -1, "UTF-8") != NULL);
+ }
+ /* Assume this for compatibility at present. */
+ *a = "US-ASCII";
+ xkl_debug(150, "Using charset fallback: [%s]\n", *a);
+
+ return FALSE;
}
-char *_XklLocaleFromUtf8( const char *utf8string )
+gchar *
+xkl_locale_from_utf8(const gchar * utf8string)
{
- size_t len;
-
- iconv_t converter;
- char converted[XKL_MAX_CI_DESC_LENGTH];
- char *convertedStart = converted;
- char *utfStart = ( char * ) utf8string;
- size_t clen = XKL_MAX_CI_DESC_LENGTH - 1;
- const char *charset;
-
- static Bool alreadyWarned = False;
-
- if( utf8string == NULL )
- return NULL;
-
- len = strlen( utf8string );
-
- if( _XklGetCharset( &charset ) )
- return strdup( utf8string );
-
- converter = iconv_open( charset, "UTF-8" );
- if( converter == ( iconv_t ) - 1 )
- {
- if( !alreadyWarned )
- {
- alreadyWarned = True;
- XklDebug( 0,
- "Unable to convert MIME info from UTF-8 to the current locale %s. MIME info will probably display wrong.",
- charset );
- }
- return strdup( utf8string );
- }
-
- if( iconv( converter, &utfStart, &len, &convertedStart, &clen ) == -1 )
- {
- XklDebug( 0,
- "Unable to convert %s from UTF-8 to %s, this string will probably display wrong.",
- utf8string, charset );
- return strdup( utf8string );
- }
- *convertedStart = '\0';
-
- iconv_close( converter );
-
- return strdup( converted );
+ size_t len;
+
+ iconv_t converter;
+ gchar converted[XKL_MAX_CI_DESC_LENGTH];
+ gchar *converted_start = converted;
+ gchar *utf_start = (char *) utf8string;
+ size_t clen = XKL_MAX_CI_DESC_LENGTH - 1;
+ const gchar *charset;
+
+ static gboolean already_warned = FALSE;
+
+ if (utf8string == NULL)
+ return NULL;
+
+ len = strlen(utf8string);
+
+ if (xkl_get_charset(&charset))
+ return g_strdup(utf8string);
+
+ converter = iconv_open(charset, "UTF-8");
+ if (converter == (iconv_t) - 1) {
+ if (!already_warned) {
+ already_warned = TRUE;
+ xkl_debug(0,
+ "Unable to convert MIME info from UTF-8 "
+ "to the current locale %s. "
+ "MIME info will probably display wrong.",
+ charset);
+ }
+ return g_strdup(utf8string);
+ }
+
+ if (iconv(converter, &utf_start, &len, &converted_start, &clen) ==
+ -1) {
+ xkl_debug(0,
+ "Unable to convert %s from UTF-8 to %s, "
+ "this string will probably display wrong.",
+ utf8string, charset);
+ return g_strdup(utf8string);
+ }
+ *converted_start = '\0';
+
+ iconv_close(converter);
+
+ return g_strdup(converted);
}
/*
* country[_LANG[.ENCODING]] - any other ideas?
*/
-void _XklI18NInit( void )
+void
+xkl_i18n_init(void)
{
- char *dotPos;
- char *underscorePos;
- const char *locale = NULL;
- char *curSubstring;
+ gchar *dot_pos;
+ gchar *underscore_pos;
+ const gchar *locale = NULL;
+ gchar *cur_substring;
- localeSubStrings[0][0] = localeSubStrings[1][0] =
- localeSubStrings[2][0] = '\0';
+ locale_sub_strings[0][0] = locale_sub_strings[1][0] =
+ locale_sub_strings[2][0] = '\0';
#ifdef HAVE_SETLOCALE
- locale = setlocale( LC_MESSAGES, NULL );
+ locale = setlocale(LC_MESSAGES, NULL);
#endif
- if( locale == NULL || locale[0] == '\0' )
- {
- locale = getenv( "LC_MESSAGES" );
- if( locale == NULL || locale[0] == '\0' )
- {
- locale = getenv( "LC_ALL" );
- if( locale == NULL || locale[0] == '\0' )
- locale = getenv( "LANG" );
- else
- locale = _XklParseLC_ALL2LC_MESSAGES( locale );
- }
- }
-
- if( locale == NULL )
- {
- XklDebug( 0, "Could not find locale - can be problems with i18n" );
- return;
- }
-
- strncpy( localeSubStrings[0], locale, MAX_LOCALE_LEN );
-
- curSubstring = localeSubStrings[1];
-
- dotPos = strchr( locale, '.' );
- if( dotPos != NULL )
- {
- int idx = dotPos - locale;
- if( idx >= MAX_LOCALE_LEN )
- idx = MAX_LOCALE_LEN - 1;
- strncpy( curSubstring, locale, idx );
- curSubstring[idx] = '\0';
- curSubstring += MAX_LOCALE_LEN;
- }
-
- underscorePos = strchr( locale, '_' );
- if( underscorePos != NULL && ( dotPos == NULL || dotPos > underscorePos ) )
- {
- int idx = underscorePos - locale;
- if( idx >= MAX_LOCALE_LEN )
- idx = MAX_LOCALE_LEN - 1;
- strncpy( curSubstring, locale, idx );
- curSubstring[idx] = '\0';
- }
-
- XklDebug( 150, "Locale search order:\n" );
- XklDebug( 150, " 0: %s\n", localeSubStrings[0] ); /* full locale - highest priority */
- XklDebug( 150, " 1: %s\n", localeSubStrings[1] );
- XklDebug( 150, " 2: %s\n", localeSubStrings[2] );
+ if (locale == NULL || locale[0] == '\0') {
+ locale = getenv("LC_MESSAGES");
+ if (locale == NULL || locale[0] == '\0') {
+ locale = getenv("LC_ALL");
+ if (locale == NULL || locale[0] == '\0')
+ locale = getenv("LANG");
+ else
+ locale =
+ xkl_parse_LC_ALL_to_LC_MESSAGES
+ (locale);
+ }
+ }
+
+ if (locale == NULL) {
+ xkl_debug(0,
+ "Could not find locale - can be problems with i18n");
+ return;
+ }
+
+ g_strlcpy(locale_sub_strings[0], locale, MAX_LOCALE_LEN);
+
+ cur_substring = locale_sub_strings[1];
+
+ dot_pos = g_strstr_len(locale, -1, ".");
+ if (dot_pos != NULL) {
+ gint idx = dot_pos - locale;
+ if (idx >= MAX_LOCALE_LEN)
+ idx = MAX_LOCALE_LEN - 1;
+ g_strlcpy(cur_substring, locale, idx);
+ cur_substring += MAX_LOCALE_LEN;
+ }
+
+ underscore_pos = strchr(locale, '_');
+ if (underscore_pos != NULL &&
+ (dot_pos == NULL || dot_pos > underscore_pos)) {
+ gint idx = underscore_pos - locale;
+ if (idx >= MAX_LOCALE_LEN)
+ idx = MAX_LOCALE_LEN - 1;
+ g_strlcpy(cur_substring, locale, idx);
+ }
+
+ xkl_debug(150, "Locale search order:\n");
+ /* full locale - highest priority */
+ xkl_debug(150, " 0: %s\n", locale_sub_strings[0]);
+ xkl_debug(150, " 1: %s\n", locale_sub_strings[1]);
+ xkl_debug(150, " 2: %s\n", locale_sub_strings[2]);
}
-int _XklGetLanguagePriority( const char *lang )
+gint
+xkl_get_language_priority(const gchar * lang)
{
- int i, priority = -1;
-
- for( i = sizeof( localeSubStrings ) / sizeof( localeSubStrings[0] );
- --i >= 0; )
- {
- if( localeSubStrings[0][0] == '\0' )
- continue;
-
- if( !strcmp( lang, localeSubStrings[i] ) )
- {
- priority = i;
- break;
- }
- }
- return priority;
+ gint i, priority = -1;
+
+ for (i =
+ sizeof(locale_sub_strings) / sizeof(locale_sub_strings[0]);
+ --i >= 0;) {
+ if (locale_sub_strings[0][0] == '\0')
+ continue;
+
+ if (!g_ascii_strcasecmp(lang, locale_sub_strings[i])) {
+ priority = i;
+ break;
+ }
+ }
+ return priority;
}
diff --git a/libxklavier/xklavier_config_xkb.c b/libxklavier/xklavier_config_xkb.c
index 05843fe..39b74e8 100644
--- a/libxklavier/xklavier_config_xkb.c
+++ b/libxklavier/xklavier_config_xkb.c
@@ -1,6 +1,6 @@
#include <errno.h>
-#include <string.h>
#include <locale.h>
+#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/param.h>
@@ -30,415 +30,504 @@
#include <X11/keysymdef.h>
#ifdef XKB_HEADERS_PRESENT
-static XkbRF_RulesPtr _xklRules;
+static XkbRF_RulesPtr xkl_rules;
-static XkbRF_RulesPtr _XklLoadRulesSet( void )
+static XkbRF_RulesPtr
+xkl_rules_set_load(XklEngine * engine)
{
- XkbRF_RulesPtr rulesSet = NULL;
- char fileName[MAXPATHLEN] = "";
- char *rf = _XklGetRulesSetName( XKB_DEFAULT_RULESET );
- char *locale = NULL;
-
- if( rf == NULL )
- {
- _xklLastErrorMsg = "Could not find the XKB rules set";
- return NULL;
- }
-
- locale = setlocale( LC_ALL, NULL );
-
- snprintf( fileName, sizeof fileName, XKB_BASE "/rules/%s", rf );
- XklDebug( 160, "Loading rules from [%s]\n", fileName );
-
- rulesSet = XkbRF_Load( fileName, locale, True, True );
-
- if( rulesSet == NULL )
- {
- _xklLastErrorMsg = "Could not load rules";
- return NULL;
- }
- return rulesSet;
+ XkbRF_RulesPtr rules_set = NULL;
+ char file_name[MAXPATHLEN] = "";
+ char *rf =
+ xkl_engine_get_ruleset_name(engine, XKB_DEFAULT_RULESET);
+ char *locale = NULL;
+
+ if (rf == NULL) {
+ xkl_last_error_message =
+ "Could not find the XKB rules set";
+ return NULL;
+ }
+
+ locale = setlocale(LC_ALL, NULL);
+
+ snprintf(file_name, sizeof file_name, XKB_BASE "/rules/%s", rf);
+ xkl_debug(160, "Loading rules from [%s]\n", file_name);
+
+ rules_set = XkbRF_Load(file_name, locale, True, True);
+
+ if (rules_set == NULL) {
+ xkl_last_error_message = "Could not load rules";
+ return NULL;
+ }
+ return rules_set;
}
-static void _XklFreeRulesSet( void )
+static void
+xkl_rules_set_free(void)
{
- if ( _xklRules )
- XkbRF_Free( _xklRules, True );
- _xklRules = NULL;
+ if (xkl_rules)
+ XkbRF_Free(xkl_rules, True);
+ xkl_rules = NULL;
}
#endif
-void _XklXkbConfigInit( void )
+void
+xkl_xkb_init_config_registry(XklConfigRegistry * config)
{
#ifdef XKB_HEADERS_PRESENT
- XkbInitAtoms( NULL );
+ XkbInitAtoms(NULL);
#endif
}
-Bool _XklXkbConfigLoadRegistry( void )
+gboolean
+xkl_xkb_load_config_registry(XklConfigRegistry * config)
{
- struct stat statBuf;
- char fileName[MAXPATHLEN] = "";
- char* rf = _XklGetRulesSetName( XKB_DEFAULT_RULESET );
+ struct stat stat_buf;
+ char file_name[MAXPATHLEN] = "";
+ char *rf =
+ xkl_engine_get_ruleset_name(xkl_config_registry_get_engine
+ (config),
+ XKB_DEFAULT_RULESET);
- if ( rf == NULL )
- return False;
+ if (rf == NULL)
+ return FALSE;
- snprintf( fileName, sizeof fileName, XKB_BASE "/rules/%s.xml", rf );
+ snprintf(file_name, sizeof file_name, XKB_BASE "/rules/%s.xml",
+ rf);
- if( stat( fileName, &statBuf ) != 0 )
- {
- strncpy( fileName, XML_CFG_FALLBACK_PATH, sizeof fileName );
- fileName[ MAXPATHLEN - 1 ] = '\0';
- }
+ if (stat(file_name, &stat_buf) != 0) {
+ g_strlcpy(file_name, XML_CFG_FALLBACK_PATH,
+ sizeof file_name);
+ }
- return XklConfigLoadRegistryFromFile( fileName );
+ return xkl_config_registry_load_from_file(config, file_name);
}
#ifdef XKB_HEADERS_PRESENT
-Bool _XklXkbConfigPrepareNative( const XklConfigRecPtr data, XkbComponentNamesPtr componentNamesPtr )
+gboolean
+xkl_xkb_config_native_prepare(XklEngine * engine,
+ const XklConfigRec * data,
+ XkbComponentNamesPtr component_names_ptr)
{
- XkbRF_VarDefsRec _xklVarDefs;
- Bool gotComponents;
-
- memset( &_xklVarDefs, 0, sizeof( _xklVarDefs ) );
-
- _xklRules = _XklLoadRulesSet();
- if( !_xklRules )
- {
- return False;
- }
-
- _xklVarDefs.model = ( char * ) data->model;
-
- if( data->layouts != NULL )
- _xklVarDefs.layout = _XklConfigRecMergeLayouts( data );
-
- if( data->variants != NULL )
- _xklVarDefs.variant = _XklConfigRecMergeVariants( data );
-
- if( data->options != NULL )
- _xklVarDefs.options = _XklConfigRecMergeOptions( data );
-
- gotComponents = XkbRF_GetComponents( _xklRules, &_xklVarDefs, componentNamesPtr );
-
- free( _xklVarDefs.layout );
- free( _xklVarDefs.variant );
- free( _xklVarDefs.options );
-
- if( !gotComponents )
- {
- _xklLastErrorMsg = "Could not translate rules into components";
- /* Just cleanup the stuff in case of failure */
- _XklXkbConfigCleanupNative( componentNamesPtr );
-
- return False;
- }
-
- if ( _xklDebugLevel >= 200 )
- {
- XklDebug( 200, "keymap: %s\n", componentNamesPtr->keymap );
- XklDebug( 200, "keycodes: %s\n", componentNamesPtr->keycodes );
- XklDebug( 200, "compat: %s\n", componentNamesPtr->compat );
- XklDebug( 200, "types: %s\n", componentNamesPtr->types );
- XklDebug( 200, "symbols: %s\n", componentNamesPtr->symbols );
- XklDebug( 200, "geometry: %s\n", componentNamesPtr->geometry );
- }
- return True;
+ XkbRF_VarDefsRec xkl_var_defs;
+ gboolean got_components;
+
+ memset(&xkl_var_defs, 0, sizeof(xkl_var_defs));
+
+ xkl_rules = xkl_rules_set_load(engine);
+ if (!xkl_rules) {
+ return FALSE;
+ }
+
+ xkl_var_defs.model = (char *) data->model;
+
+ if (data->layouts != NULL)
+ xkl_var_defs.layout = xkl_config_rec_merge_layouts(data);
+
+ if (data->variants != NULL)
+ xkl_var_defs.variant = xkl_config_rec_merge_variants(data);
+
+ if (data->options != NULL)
+ xkl_var_defs.options = xkl_config_rec_merge_options(data);
+
+ got_components =
+ XkbRF_GetComponents(xkl_rules, &xkl_var_defs,
+ component_names_ptr);
+
+ g_free(xkl_var_defs.layout);
+ g_free(xkl_var_defs.variant);
+ g_free(xkl_var_defs.options);
+
+ if (!got_components) {
+ xkl_last_error_message =
+ "Could not translate rules into components";
+ /* Just cleanup the stuff in case of failure */
+ xkl_xkb_config_native_cleanup(engine, component_names_ptr);
+
+ return FALSE;
+ }
+
+ if (xkl_debug_level >= 200) {
+ xkl_debug(200, "keymap: %s\n",
+ component_names_ptr->keymap);
+ xkl_debug(200, "keycodes: %s\n",
+ component_names_ptr->keycodes);
+ xkl_debug(200, "compat: %s\n",
+ component_names_ptr->compat);
+ xkl_debug(200, "types: %s\n", component_names_ptr->types);
+ xkl_debug(200, "symbols: %s\n",
+ component_names_ptr->symbols);
+ xkl_debug(200, "geometry: %s\n",
+ component_names_ptr->geometry);
+ }
+ return TRUE;
}
-void _XklXkbConfigCleanupNative( XkbComponentNamesPtr componentNamesPtr )
+void
+xkl_xkb_config_native_cleanup(XklEngine * engine,
+ XkbComponentNamesPtr component_names_ptr)
{
- _XklFreeRulesSet();
-
- free(componentNamesPtr->keymap);
- free(componentNamesPtr->keycodes);
- free(componentNamesPtr->compat);
- free(componentNamesPtr->types);
- free(componentNamesPtr->symbols);
- free(componentNamesPtr->geometry);
+ xkl_rules_set_free();
+
+ g_free(component_names_ptr->keymap);
+ g_free(component_names_ptr->keycodes);
+ g_free(component_names_ptr->compat);
+ g_free(component_names_ptr->types);
+ g_free(component_names_ptr->symbols);
+ g_free(component_names_ptr->geometry);
}
-static XkbDescPtr _XklConfigGetKeyboard( XkbComponentNamesPtr componentNamesPtr, Bool activate )
+static XkbDescPtr
+xkl_config_get_keyboard(XklEngine * engine,
+ XkbComponentNamesPtr component_names_ptr,
+ gboolean activate)
{
- XkbDescPtr xkb = NULL;
+ XkbDescPtr xkb = NULL;
#if 0
- xkb = XkbGetKeyboardByName( _xklDpy,
- XkbUseCoreKbd,
- &componentNames,
- XkbGBN_AllComponentsMask &
- ( ~XkbGBN_GeometryMask ),
- XkbGBN_AllComponentsMask &
- ( ~XkbGBN_GeometryMask ),
- activate );
+ xkb = XkbGetKeyboardByName(_xklDpy,
+ XkbUseCoreKbd,
+ &componentNames,
+ XkbGBN_AllComponentsMask &
+ (~XkbGBN_GeometryMask),
+ XkbGBN_AllComponentsMask &
+ (~XkbGBN_GeometryMask), activate);
#else
- char xkmFN[L_tmpnam];
- char xkbFN[L_tmpnam];
- FILE* tmpxkm;
- XkbFileInfo result;
- int xkmloadres;
-
- if ( tmpnam( xkmFN ) != NULL &&
- tmpnam( xkbFN ) != NULL )
- {
- pid_t cpid, pid;
- int status = 0;
- FILE *tmpxkb;
-
- XklDebug( 150, "tmp XKB/XKM file names: [%s]/[%s]\n", xkbFN, xkmFN );
- if( (tmpxkb = fopen( xkbFN, "w" )) != NULL )
- {
- fprintf( tmpxkb, "xkb_keymap {\n" );
- fprintf( tmpxkb, " xkb_keycodes { include \"%s\" };\n", componentNamesPtr->keycodes );
- fprintf( tmpxkb, " xkb_types { include \"%s\" };\n", componentNamesPtr->types );
- fprintf( tmpxkb, " xkb_compat { include \"%s\" };\n", componentNamesPtr->compat );
- fprintf( tmpxkb, " xkb_symbols { include \"%s\" };\n", componentNamesPtr->symbols );
- fprintf( tmpxkb, " xkb_geometry { include \"%s\" };\n", componentNamesPtr->geometry );
- fprintf( tmpxkb, "};\n" );
- fclose( tmpxkb );
-
- XklDebug( 150, "xkb_keymap {\n"
- " xkb_keycodes { include \"%s\" };\n"
- " xkb_types { include \"%s\" };\n"
- " xkb_compat { include \"%s\" };\n"
- " xkb_symbols { include \"%s\" };\n"
- " xkb_geometry { include \"%s\" };\n};\n",
- componentNamesPtr->keycodes,
- componentNamesPtr->types,
- componentNamesPtr->compat,
- componentNamesPtr->symbols,
- componentNamesPtr->geometry );
-
- cpid=fork();
- switch( cpid )
- {
- case -1:
- XklDebug( 0, "Could not fork: %d\n", errno );
- break;
- case 0:
- /* child */
- XklDebug( 160, "Executing %s\n", XKBCOMP );
- XklDebug( 160, "%s %s %s %s %s %s %s\n",
- XKBCOMP, XKBCOMP, "-I", "-I" XKB_BASE, "-xkm", xkbFN, xkmFN );
- execl( XKBCOMP, XKBCOMP, "-I", "-I" XKB_BASE, "-xkm", xkbFN, xkmFN, NULL );
- XklDebug( 0, "Could not exec %s: %d\n", XKBCOMP, errno );
- exit( 1 );
- default:
- /* parent */
- pid = waitpid( cpid, &status, 0 );
- XklDebug( 150, "Return status of %d (well, started %d): %d\n", pid, cpid, status );
- memset( (char *)&result, 0, sizeof(result) );
- result.xkb = XkbAllocKeyboard();
-
- if( Success == XkbChangeKbdDisplay( _xklDpy, &result ) )
- {
- XklDebug( 150, "Hacked the kbddesc - set the display...\n" );
- if( (tmpxkm = fopen( xkmFN, "r" )) != NULL )
- {
- xkmloadres = XkmReadFile( tmpxkm, XkmKeymapLegal, XkmKeymapLegal, &result);
- XklDebug( 150, "Loaded %s output as XKM file, got %d (comparing to %d)\n",
- XKBCOMP, (int)xkmloadres, (int)XkmKeymapLegal );
- if ( (int)xkmloadres != (int)XkmKeymapLegal )
- {
- XklDebug( 150, "Loaded legal keymap\n" );
- if( activate )
- {
- XklDebug( 150, "Activating it...\n" );
- if( XkbWriteToServer(&result) )
- {
- XklDebug( 150, "Updating the keyboard...\n" );
- xkb = result.xkb;
- } else
- {
- XklDebug( 0, "Could not write keyboard description to the server\n" );
- }
- } else /* no activate, just load */
- xkb = result.xkb;
- } else /* could not load properly */
- {
- XklDebug( 0, "Could not load %s output as XKM file, got %d (asked %d)\n",
- XKBCOMP, (int)xkmloadres, (int)XkmKeymapLegal );
- }
- fclose( tmpxkm );
- XklDebug( 160, "Unlinking the temporary xkm file %s\n", xkmFN );
- if ( _xklDebugLevel < 500 ) /* don't remove on high debug levels! */
- {
- if ( remove( xkmFN ) == -1 )
- XklDebug( 0, "Could not unlink the temporary xkm file %s: %d\n",
- xkmFN, errno );
- } else
- XklDebug( 500, "Well, not really - the debug level is too high: %d\n", _xklDebugLevel );
- } else /* could not open the file */
- {
- XklDebug( 0, "Could not open the temporary xkm file %s\n", xkmFN );
- }
- } else /* could not assign to display */
- {
- XklDebug( 0, "Could not change the keyboard description to display\n" );
- }
- if ( xkb == NULL )
- XkbFreeKeyboard( result.xkb, XkbAllComponentsMask, True );
- break;
- }
- XklDebug( 160, "Unlinking the temporary xkb file %s\n", xkbFN );
- if ( _xklDebugLevel < 500 ) /* don't remove on high debug levels! */
- {
- if ( remove( xkbFN ) == -1 )
- XklDebug( 0, "Could not unlink the temporary xkb file %s: %d\n",
- xkbFN, errno );
- } else
- XklDebug( 500, "Well, not really - the debug level is too high: %d\n", _xklDebugLevel );
- } else /* could not open input tmp file */
- {
- XklDebug( 0, "Could not open tmp XKB file [%s]: %d\n", xkbFN, errno );
- }
- } else
- {
- XklDebug( 0, "Could not get tmp names\n" );
- }
+ char xkm_fn[L_tmpnam];
+ char xkb_fn[L_tmpnam];
+ FILE *tmpxkm;
+ XkbFileInfo result;
+ int xkmloadres;
+
+ Display *display = xkl_engine_get_display(engine);
+
+ if (tmpnam(xkm_fn) != NULL && tmpnam(xkb_fn) != NULL) {
+ pid_t cpid, pid;
+ int status = 0;
+ FILE *tmpxkb;
+
+ xkl_debug(150, "tmp XKB/XKM file names: [%s]/[%s]\n",
+ xkb_fn, xkm_fn);
+ if ((tmpxkb = fopen(xkb_fn, "w")) != NULL) {
+ fprintf(tmpxkb, "xkb_keymap {\n");
+ fprintf(tmpxkb,
+ " xkb_keycodes { include \"%s\" };\n",
+ component_names_ptr->keycodes);
+ fprintf(tmpxkb,
+ " xkb_types { include \"%s\" };\n",
+ component_names_ptr->types);
+ fprintf(tmpxkb,
+ " xkb_compat { include \"%s\" };\n",
+ component_names_ptr->compat);
+ fprintf(tmpxkb,
+ " xkb_symbols { include \"%s\" };\n",
+ component_names_ptr->symbols);
+ fprintf(tmpxkb,
+ " xkb_geometry { include \"%s\" };\n",
+ component_names_ptr->geometry);
+ fprintf(tmpxkb, "};\n");
+ fclose(tmpxkb);
+
+ xkl_debug(150, "xkb_keymap {\n"
+ " xkb_keycodes { include \"%s\" };\n"
+ " xkb_types { include \"%s\" };\n"
+ " xkb_compat { include \"%s\" };\n"
+ " xkb_symbols { include \"%s\" };\n"
+ " xkb_geometry { include \"%s\" };\n};\n",
+ component_names_ptr->keycodes,
+ component_names_ptr->types,
+ component_names_ptr->compat,
+ component_names_ptr->symbols,
+ component_names_ptr->geometry);
+
+ cpid = fork();
+ switch (cpid) {
+ case -1:
+ xkl_debug(0, "Could not fork: %d\n",
+ errno);
+ break;
+ case 0:
+ /* child */
+ xkl_debug(160, "Executing %s\n", XKBCOMP);
+ xkl_debug(160, "%s %s %s %s %s %s %s\n",
+ XKBCOMP, XKBCOMP, "-I",
+ "-I" XKB_BASE, "-xkm", xkb_fn,
+ xkm_fn);
+ execl(XKBCOMP, XKBCOMP, "-I",
+ "-I" XKB_BASE, "-xkm", xkb_fn,
+ xkm_fn, NULL);
+ xkl_debug(0, "Could not exec %s: %d\n",
+ XKBCOMP, errno);
+ exit(1);
+ default:
+ /* parent */
+ pid = waitpid(cpid, &status, 0);
+ xkl_debug(150,
+ "Return status of %d (well, started %d): %d\n",
+ pid, cpid, status);
+ memset((char *) &result, 0,
+ sizeof(result));
+ result.xkb = XkbAllocKeyboard();
+
+ if (Success ==
+ XkbChangeKbdDisplay(display,
+ &result)) {
+ xkl_debug(150,
+ "Hacked the kbddesc - set the display...\n");
+ if ((tmpxkm =
+ fopen(xkm_fn, "r")) != NULL) {
+ xkmloadres =
+ XkmReadFile(tmpxkm,
+ XkmKeymapLegal,
+ XkmKeymapLegal,
+ &result);
+ xkl_debug(150,
+ "Loaded %s output as XKM file, got %d (comparing to %d)\n",
+ XKBCOMP,
+ (int) xkmloadres,
+ (int)
+ XkmKeymapLegal);
+ if ((int) xkmloadres !=
+ (int) XkmKeymapLegal) {
+ xkl_debug(150,
+ "Loaded legal keymap\n");
+ if (activate) {
+ xkl_debug
+ (150,
+ "Activating it...\n");
+ if (XkbWriteToServer(&result)) {
+ xkl_debug
+ (150,
+ "Updating the keyboard...\n");
+ xkb = result.xkb;
+ } else {
+ xkl_debug
+ (0,
+ "Could not write keyboard description to the server\n");
+ }
+ } else /* no activate, just load */
+ xkb =
+ result.
+ xkb;
+ } else { /* could not load properly */
+
+ xkl_debug(0,
+ "Could not load %s output as XKM file, got %d (asked %d)\n",
+ XKBCOMP,
+ (int)
+ xkmloadres,
+ (int)
+ XkmKeymapLegal);
+ }
+ fclose(tmpxkm);
+ xkl_debug(160,
+ "Unlinking the temporary xkm file %s\n",
+ xkm_fn);
+ if (xkl_debug_level < 500) { /* don't remove on high debug levels! */
+ if (remove(xkm_fn)
+ == -1)
+ xkl_debug
+ (0,
+ "Could not unlink the temporary xkm file %s: %d\n",
+ xkm_fn,
+ errno);
+ } else
+ xkl_debug(500,
+ "Well, not really - the debug level is too high: %d\n",
+ xkl_debug_level);
+ } else { /* could not open the file */
+
+ xkl_debug(0,
+ "Could not open the temporary xkm file %s\n",
+ xkm_fn);
+ }
+ } else { /* could not assign to display */
+
+ xkl_debug(0,
+ "Could not change the keyboard description to display\n");
+ }
+ if (xkb == NULL)
+ XkbFreeKeyboard(result.xkb,
+ XkbAllComponentsMask,
+ True);
+ break;
+ }
+ xkl_debug(160,
+ "Unlinking the temporary xkb file %s\n",
+ xkb_fn);
+ if (xkl_debug_level < 500) { /* don't remove on high debug levels! */
+ if (remove(xkb_fn) == -1)
+ xkl_debug(0,
+ "Could not unlink the temporary xkb file %s: %d\n",
+ xkb_fn, errno);
+ } else
+ xkl_debug(500,
+ "Well, not really - the debug level is too high: %d\n",
+ xkl_debug_level);
+ } else { /* could not open input tmp file */
+
+ xkl_debug(0,
+ "Could not open tmp XKB file [%s]: %d\n",
+ xkb_fn, errno);
+ }
+ } else {
+ xkl_debug(0, "Could not get tmp names\n");
+ }
#endif
- return xkb;
+ return xkb;
}
-#else /* no XKB headers */
-Bool _XklXkbConfigPrepareNative( const XklConfigRecPtr data, void * componentNamesPtr )
+#else /* no XKB headers */
+gboolean
+xkl_xkb_config_native_prepare(const XklConfigRec * data,
+ gpointer componentNamesPtr)
{
- return False;
+ return FALSE;
}
-void _XklXkbConfigCleanupNative( void * componentNamesPtr )
+void
+_XklXkbConfigCleanupNative(gpointer componentNamesPtr)
{
}
#endif
/* check only client side support */
-Bool _XklXkbConfigMultipleLayoutsSupported( void )
+gboolean
+xkl_xkb_multiple_layouts_supported(XklEngine * engine)
{
- enum { NON_SUPPORTED, SUPPORTED, UNCHECKED };
+ enum { NON_SUPPORTED, SUPPORTED, UNCHECKED };
- static int supportState = UNCHECKED;
+ static int support_state = UNCHECKED;
- if( supportState == UNCHECKED )
- {
- XklConfigRec data;
- char *layouts[] = { "us", "de" };
- char *variants[] = { NULL, NULL };
+ if (support_state == UNCHECKED) {
+ XklConfigRec data;
+ char *layouts[] = { "us", "de", NULL };
+ char *variants[] = { NULL, NULL, NULL };
#ifdef XKB_HEADERS_PRESENT
- XkbComponentNamesRec componentNames;
- memset( &componentNames, 0, sizeof( componentNames ) );
+ XkbComponentNamesRec component_names;
+ memset(&component_names, 0, sizeof(component_names));
#endif
- data.model = "pc105";
- data.numVariants =
- data.numLayouts = 2;
- data.numOptions = 0;
- data.layouts = layouts;
- data.variants = variants;
- data.options = NULL;
+ data.model = "pc105";
+ data.layouts = layouts;
+ data.variants = variants;
+ data.options = NULL;
- XklDebug( 100, "!!! Checking multiple layouts support\n" );
- supportState = NON_SUPPORTED;
+ xkl_debug(100, "!!! Checking multiple layouts support\n");
+ support_state = NON_SUPPORTED;
#ifdef XKB_HEADERS_PRESENT
- if( _XklXkbConfigPrepareNative( &data, &componentNames ) )
- {
- XklDebug( 100, "!!! Multiple layouts ARE supported\n" );
- supportState = SUPPORTED;
- _XklXkbConfigCleanupNative( &componentNames );
- } else
- {
- XklDebug( 100, "!!! Multiple layouts ARE NOT supported\n" );
- }
+ if (xkl_xkb_config_native_prepare
+ (engine, &data, &component_names)) {
+ xkl_debug(100,
+ "!!! Multiple layouts ARE supported\n");
+ support_state = SUPPORTED;
+ xkl_xkb_config_native_cleanup(engine,
+ &component_names);
+ } else {
+ xkl_debug(100,
+ "!!! Multiple layouts ARE NOT supported\n");
+ }
#endif
- }
- return supportState == SUPPORTED;
+ }
+ return support_state == SUPPORTED;
}
-Bool _XklXkbConfigActivate( const XklConfigRecPtr data )
+gboolean
+xkl_xkb_activate_config_rec(XklEngine * engine, const XklConfigRec * data)
{
- Bool rv = False;
+ gboolean rv = FALSE;
#if 0
- {
- int i;
- XklDebug( 150, "New model: [%s]\n", data->model );
- XklDebug( 150, "New layouts: %p\n", data->layouts );
- for( i = data->numLayouts; --i >= 0; )
- XklDebug( 150, "New layout[%d]: [%s]\n", i, data->layouts[i] );
- XklDebug( 150, "New variants: %p\n", data->variants );
- for( i = data->numVariants; --i >= 0; )
- XklDebug( 150, "New variant[%d]: [%s]\n", i, data->variants[i] );
- XklDebug( 150, "New options: %p\n", data->options );
- for( i = data->numOptions; --i >= 0; )
- XklDebug( 150, "New option[%d]: [%s]\n", i, data->options[i] );
- }
+ {
+ int i;
+ XklDebug(150, "New model: [%s]\n", data->model);
+ XklDebug(150, "New layouts: %p\n", data->layouts);
+ for (i = data->numLayouts; --i >= 0;)
+ XklDebug(150, "New layout[%d]: [%s]\n", i,
+ data->layouts[i]);
+ XklDebug(150, "New variants: %p\n", data->variants);
+ for (i = data->numVariants; --i >= 0;)
+ XklDebug(150, "New variant[%d]: [%s]\n", i,
+ data->variants[i]);
+ XklDebug(150, "New options: %p\n", data->options);
+ for (i = data->numOptions; --i >= 0;)
+ XklDebug(150, "New option[%d]: [%s]\n", i,
+ data->options[i]);
+ }
#endif
#ifdef XKB_HEADERS_PRESENT
- XkbComponentNamesRec componentNames;
- memset( &componentNames, 0, sizeof( componentNames ) );
-
- if( _XklXkbConfigPrepareNative( data, &componentNames ) )
- {
- XkbDescPtr xkb;
- xkb = _XklConfigGetKeyboard( &componentNames, True );
- if( xkb != NULL )
- {
- if( XklSetNamesProp
- ( xklVTable->baseConfigAtom, _XklGetRulesSetName( XKB_DEFAULT_RULESET ), data ) )
- /* We do not need to check the result of _XklGetRulesSetName -
- because PrepareBeforeKbd did it for us */
- rv = True;
- else
- _xklLastErrorMsg = "Could not set names property";
- XkbFreeKeyboard( xkb, XkbAllComponentsMask, True );
- } else
- {
- _xklLastErrorMsg = "Could not load keyboard description";
- }
- _XklXkbConfigCleanupNative( &componentNames );
- }
+ XkbComponentNamesRec component_names;
+ memset(&component_names, 0, sizeof(component_names));
+
+ if (xkl_xkb_config_native_prepare(engine, data, &component_names)) {
+ XkbDescPtr xkb;
+ xkb =
+ xkl_config_get_keyboard(engine, &component_names,
+ TRUE);
+ if (xkb != NULL) {
+ if (xkl_config_rec_set_to_root_window_property
+ (data,
+ xkl_engine_priv(engine, base_config_atom),
+ xkl_engine_get_ruleset_name(engine,
+ XKB_DEFAULT_RULESET),
+ engine))
+ /* We do not need to check the result of _XklGetRulesSetName -
+ because PrepareBeforeKbd did it for us */
+ rv = TRUE;
+ else
+ xkl_last_error_message =
+ "Could not set names property";
+ XkbFreeKeyboard(xkb, XkbAllComponentsMask, True);
+ } else {
+ xkl_last_error_message =
+ "Could not load keyboard description";
+ }
+ xkl_xkb_config_native_cleanup(engine, &component_names);
+ }
#endif
- return rv;
+ return rv;
}
-Bool _XklXkbConfigWriteFile( const char *fileName,
- const XklConfigRecPtr data,
- const Bool binary )
+gboolean
+xkl_xkb_write_config_rec_to_file(XklEngine * engine, const char *file_name,
+ const XklConfigRec * data,
+ const gboolean binary)
{
- Bool rv = False;
+ gboolean rv = FALSE;
#ifdef XKB_HEADERS_PRESENT
- XkbComponentNamesRec componentNames;
- FILE *output = fopen( fileName, "w" );
- XkbFileInfo dumpInfo;
-
- if( output == NULL )
- {
- _xklLastErrorMsg = "Could not open the XKB file";
- return False;
- }
-
- memset( &componentNames, 0, sizeof( componentNames ) );
-
- if( _XklXkbConfigPrepareNative( data, &componentNames ) )
- {
- XkbDescPtr xkb;
- xkb = _XklConfigGetKeyboard( &componentNames, False );
- if( xkb != NULL )
- {
- dumpInfo.defined = 0;
- dumpInfo.xkb = xkb;
- dumpInfo.type = XkmKeymapFile;
- if( binary )
- rv = XkbWriteXKMFile( output, &dumpInfo );
- else
- rv = XkbWriteXKBFile( output, &dumpInfo, True, NULL, NULL );
-
- XkbFreeKeyboard( xkb, XkbGBN_AllComponentsMask, True );
- } else
- _xklLastErrorMsg = "Could not load keyboard description";
- _XklXkbConfigCleanupNative( &componentNames );
- }
- fclose( output );
+ XkbComponentNamesRec component_names;
+ FILE *output = fopen(file_name, "w");
+ XkbFileInfo dump_info;
+
+ if (output == NULL) {
+ xkl_last_error_message = "Could not open the XKB file";
+ return FALSE;
+ }
+
+ memset(&component_names, 0, sizeof(component_names));
+
+ if (xkl_xkb_config_native_prepare(engine, data, &component_names)) {
+ XkbDescPtr xkb;
+ xkb =
+ xkl_config_get_keyboard(engine, &component_names,
+ FALSE);
+ if (xkb != NULL) {
+ dump_info.defined = 0;
+ dump_info.xkb = xkb;
+ dump_info.type = XkmKeymapFile;
+ if (binary)
+ rv = XkbWriteXKMFile(output, &dump_info);
+ else
+ rv = XkbWriteXKBFile(output, &dump_info,
+ True, NULL, NULL);
+
+ XkbFreeKeyboard(xkb, XkbGBN_AllComponentsMask,
+ True);
+ } else
+ xkl_last_error_message =
+ "Could not load keyboard description";
+ xkl_xkb_config_native_cleanup(engine, &component_names);
+ }
+ fclose(output);
#endif
- return rv;
+ return rv;
}
diff --git a/libxklavier/xklavier_config_xmm.c b/libxklavier/xklavier_config_xmm.c
index abceec0..b18f851 100644
--- a/libxklavier/xklavier_config_xmm.c
+++ b/libxklavier/xklavier_config_xmm.c
@@ -1,6 +1,6 @@
#include <errno.h>
-#include <string.h>
#include <locale.h>
+#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/param.h>
@@ -19,37 +19,46 @@
#define XK_XKB_KEYS
#include <X11/keysymdef.h>
-void _XklXmmConfigInit( void )
+void
+xkl_xmm_init_config_registry(XklConfigRegistry * config)
{
}
-Bool _XklXmmConfigLoadRegistry( void )
+gboolean
+xkl_xmm_load_config_registry(XklConfigRegistry * config)
{
- struct stat statBuf;
- char fileName[MAXPATHLEN] = "";
- char* rf = _XklGetRulesSetName( "" );
+ struct stat stat_buf;
+ gchar file_name[MAXPATHLEN] = "";
+ XklEngine *engine = xkl_config_registry_get_engine(config);
+ gchar *rf = xkl_engine_get_ruleset_name(engine, "");
- if ( rf == NULL || rf[0] == '\0' )
- return False;
+ if (rf == NULL || rf[0] == '\0')
+ return FALSE;
- snprintf( fileName, sizeof fileName, XMODMAP_BASE "/%s.xml", rf );
+ g_snprintf(file_name, sizeof file_name, XMODMAP_BASE "/%s.xml",
+ rf);
- if( stat( fileName, &statBuf ) != 0 )
- {
- _xklLastErrorMsg = "No rules file found";
- return False;
- }
+ if (stat(file_name, &stat_buf) != 0) {
+ xkl_last_error_message = "No rules file found";
+ return FALSE;
+ }
- return XklConfigLoadRegistryFromFile( fileName );
+ return xkl_config_registry_load_from_file(config, file_name);
}
-Bool _XklXmmConfigActivate( const XklConfigRecPtr data )
+gboolean
+xkl_xmm_activate_config_rec(XklEngine * engine, const XklConfigRec * data)
{
- Bool rv;
- rv = XklSetNamesProp( xklVTable->baseConfigAtom,
- currentXmmRules,
- data );
- if( rv )
- _XklXmmLockGroup( 0 );
- return rv;
+ gboolean rv;
+ rv = xkl_config_rec_set_to_root_window_property(data,
+ xkl_engine_priv
+ (engine,
+ base_config_atom),
+ xkl_engine_backend
+ (engine, XklXmm,
+ current_rules),
+ engine);
+ if (rv)
+ xkl_xmm_lock_group(engine, 0);
+ return rv;
}
diff --git a/libxklavier/xklavier_dump.c b/libxklavier/xklavier_dump.c
index b013584..1681151 100644
--- a/libxklavier/xklavier_dump.c
+++ b/libxklavier/xklavier_dump.c
@@ -21,261 +21,264 @@
#ifdef XKB_HEADERS_PRESENT
#if 0
-static void _XkbModsRecDump( FILE * fs, XkbModsRec * mods )
+static void
+_XkbModsRecDump(FILE * fs, XkbModsRec * mods)
{
- fprintf( fs, "flags: 0x%X\n", mods->mask );
- fprintf( fs, "real_mods: 0x%X\n", mods->real_mods );
- fprintf( fs, "vmods: 0x%X\n", mods->vmods );
+ fprintf(fs, "flags: 0x%X\n", mods->mask);
+ fprintf(fs, "real_mods: 0x%X\n", mods->real_mods);
+ fprintf(fs, "vmods: 0x%X\n", mods->vmods);
}
-static void _XkbControlsDump( FILE * fs, XkbControlsPtr ctrls )
+static void
+_XkbControlsDump(FILE * fs, XkbControlsPtr ctrls)
{
- int i;
- char buf[1024];
- fprintf( fs, "mk_dflt_btn: %d\n", ctrls->mk_dflt_btn );
- fprintf( fs, "num_groups: %d\n", ctrls->num_groups );
- fprintf( fs, "groups_wrap: %d\n", ctrls->groups_wrap );
- fprintf( fs, "internal: \n" );
- _XkbModsRecDump( fs, &ctrls->internal );
- fprintf( fs, "ignore_lock: \n" );
- _XkbModsRecDump( fs, &ctrls->ignore_lock );
- fprintf( fs, "enabled_ctrls: 0x%X\n", ctrls->enabled_ctrls );
- fprintf( fs, "repeat_delay: %d\n", ctrls->repeat_delay );
- fprintf( fs, "repeat_interval: %d\n", ctrls->repeat_interval );
- fprintf( fs, "slow_keys_delay: %d\n", ctrls->slow_keys_delay );
- fprintf( fs, "debounce_delay: %d\n", ctrls->debounce_delay );
- fprintf( fs, "mk_delay: %d\n", ctrls->mk_delay );
- fprintf( fs, "mk_interval: %d\n", ctrls->mk_interval );
- fprintf( fs, "mk_time_to_max: %d\n", ctrls->mk_time_to_max );
- fprintf( fs, "mk_max_speed: %d\n", ctrls->mk_max_speed );
- fprintf( fs, "mk_curve: %d\n", ctrls->mk_curve );
- fprintf( fs, "ax_options: %d\n", ctrls->ax_options );
- fprintf( fs, "ax_timeout: %d\n", ctrls->ax_timeout );
- fprintf( fs, "axt_opts_mask: 0x%X\n", ctrls->axt_opts_mask );
- fprintf( fs, "axt_opts_values: 0x%X\n", ctrls->axt_opts_values );
- fprintf( fs, "axt_ctrls_mask: 0x%X\n", ctrls->axt_ctrls_mask );
- fprintf( fs, "axt_ctrls_values: 0x%X\n", ctrls->axt_ctrls_values );
- fprintf( fs, "axt_ctrls_values: 0x%X\n", ctrls->axt_ctrls_values );
- fprintf( fs, "per_key_repeat:\n" );
- buf[0] = 0;
- for( i = 0; i < XkbPerKeyBitArraySize; i++ )
- {
- char b[5];
- snprintf( b, sizeof( b ), "%d ", ctrls->per_key_repeat[i] );
- strcat( buf, b );
- }
- fprintf( fs, " %s\n", buf );
+ gint i;
+ gchar buf[1024];
+ fprintf(fs, "mk_dflt_btn: %d\n", ctrls->mk_dflt_btn);
+ fprintf(fs, "num_groups: %d\n", ctrls->num_groups);
+ fprintf(fs, "groups_wrap: %d\n", ctrls->groups_wrap);
+ fprintf(fs, "internal: \n");
+ _XkbModsRecDump(fs, &ctrls->internal);
+ fprintf(fs, "ignore_lock: \n");
+ _XkbModsRecDump(fs, &ctrls->ignore_lock);
+ fprintf(fs, "enabled_ctrls: 0x%X\n", ctrls->enabled_ctrls);
+ fprintf(fs, "repeat_delay: %d\n", ctrls->repeat_delay);
+ fprintf(fs, "repeat_interval: %d\n", ctrls->repeat_interval);
+ fprintf(fs, "slow_keys_delay: %d\n", ctrls->slow_keys_delay);
+ fprintf(fs, "debounce_delay: %d\n", ctrls->debounce_delay);
+ fprintf(fs, "mk_delay: %d\n", ctrls->mk_delay);
+ fprintf(fs, "mk_interval: %d\n", ctrls->mk_interval);
+ fprintf(fs, "mk_time_to_max: %d\n", ctrls->mk_time_to_max);
+ fprintf(fs, "mk_max_speed: %d\n", ctrls->mk_max_speed);
+ fprintf(fs, "mk_curve: %d\n", ctrls->mk_curve);
+ fprintf(fs, "ax_options: %d\n", ctrls->ax_options);
+ fprintf(fs, "ax_timeout: %d\n", ctrls->ax_timeout);
+ fprintf(fs, "axt_opts_mask: 0x%X\n", ctrls->axt_opts_mask);
+ fprintf(fs, "axt_opts_values: 0x%X\n", ctrls->axt_opts_values);
+ fprintf(fs, "axt_ctrls_mask: 0x%X\n", ctrls->axt_ctrls_mask);
+ fprintf(fs, "axt_ctrls_values: 0x%X\n", ctrls->axt_ctrls_values);
+ fprintf(fs, "axt_ctrls_values: 0x%X\n", ctrls->axt_ctrls_values);
+ fprintf(fs, "per_key_repeat:\n");
+ buf[0] = 0;
+ for (i = 0; i < XkbPerKeyBitArraySize; i++) {
+ gchar b[5];
+ snprintf(b, sizeof(b), "%d ", ctrls->per_key_repeat[i]);
+ strcat(buf, b);
+ }
+ fprintf(fs, " %s\n", buf);
}
#endif
-static const char *actionTypeNames[] = {
- "XkbSA_NoAction",
- "XkbSA_SetMods",
- "XkbSA_LatchMods",
- "XkbSA_LockMods",
- "XkbSA_SetGroup",
- "XkbSA_LatchGroup",
- "XkbSA_LockGroup",
- "XkbSA_MovePtr",
- "XkbSA_PtrBtn",
- "XkbSA_LockPtrBtn",
- "XkbSA_SetPtrDflt",
- "XkbSA_ISOLock",
- "XkbSA_Terminate",
- "XkbSA_SwitchScreen",
- "XkbSA_SetControls",
- "XkbSA_LockControls",
- "XkbSA_ActionMessage",
- "XkbSA_RedirectKey",
- "XkbSA_DeviceBtn",
- "XkbSA_LockDeviceBtn",
- "XkbSA_DeviceValuator"
+static const gchar *action_type_names[] = {
+ "XkbSA_NoAction",
+ "XkbSA_SetMods",
+ "XkbSA_LatchMods",
+ "XkbSA_LockMods",
+ "XkbSA_SetGroup",
+ "XkbSA_LatchGroup",
+ "XkbSA_LockGroup",
+ "XkbSA_MovePtr",
+ "XkbSA_PtrBtn",
+ "XkbSA_LockPtrBtn",
+ "XkbSA_SetPtrDflt",
+ "XkbSA_ISOLock",
+ "XkbSA_Terminate",
+ "XkbSA_SwitchScreen",
+ "XkbSA_SetControls",
+ "XkbSA_LockControls",
+ "XkbSA_ActionMessage",
+ "XkbSA_RedirectKey",
+ "XkbSA_DeviceBtn",
+ "XkbSA_LockDeviceBtn",
+ "XkbSA_DeviceValuator"
};
-static void _XkbActionDump( FILE * fs, int level, XkbAction * act )
+static void
+xkb_action_dump(FILE * fs, gint level, XkbAction * act)
{
- XkbGroupAction *ga;
- fprintf( fs, "%*stype: %d(%s)\n", level, "", act->type,
- actionTypeNames[act->type] );
- switch ( act->type )
- {
- case XkbSA_SetGroup:
- case XkbSA_LatchGroup:
- case XkbSA_LockGroup:
- ga = ( XkbGroupAction * ) act;
- fprintf( fs, "%*sXkbGroupAction: \n", level, "" );
- fprintf( fs, "%*sflags: %d\n", level, "", ga->flags );
- fprintf( fs, "%*sgroup_XXX: %d\n", level, "", ga->group_XXX );
- break;
- }
+ XkbGroupAction *ga;
+ fprintf(fs, "%*stype: %d(%s)\n", level, "", act->type,
+ action_type_names[act->type]);
+ switch (act->type) {
+ case XkbSA_SetGroup:
+ case XkbSA_LatchGroup:
+ case XkbSA_LockGroup:
+ ga = (XkbGroupAction *) act;
+ fprintf(fs, "%*sXkbGroupAction: \n", level, "");
+ fprintf(fs, "%*sflags: %d\n", level, "", ga->flags);
+ fprintf(fs, "%*sgroup_XXX: %d\n", level, "",
+ ga->group_XXX);
+ break;
+ }
}
-static void _XkbBehaviorDump( FILE * fs, int level, XkbBehavior * b )
+static void
+xkb_behavior_dump(FILE * fs, gint level, XkbBehavior * b)
{
- fprintf( fs, "%*stype: %d\n", level, "", b->type );
- fprintf( fs, "%*sdata: %d\n", level, "", b->data );
+ fprintf(fs, "%*stype: %d\n", level, "", b->type);
+ fprintf(fs, "%*sdata: %d\n", level, "", b->data);
}
-static void _XkbServerMapDump( FILE * fs, int level, XkbServerMapPtr server,
- XkbDescPtr kbd )
+static void
+xkb_server_map_dump(FILE * fs, gint level, XkbServerMapPtr server,
+ XkbDescPtr kbd)
{
- int i;
- XkbAction *pa = server->acts;
- XkbBehavior *pb = server->behaviors;
- fprintf( fs, "%*snum_acts: %d\n", level, "", server->num_acts );
- fprintf( fs, "%*ssize_acts: %d\n", level, "", server->size_acts );
- if( server->acts != NULL )
- {
- for( i = 0; i < server->num_acts; i++ )
- {
- fprintf( fs, "%*sacts[%d]:\n", level, "", i );
- _XkbActionDump( fs, level + 2, pa++ );
- }
- } else
- fprintf( fs, "%*sNO acts\n", level, "" );
+ gint i;
+ XkbAction *pa = server->acts;
+ XkbBehavior *pb = server->behaviors;
+ fprintf(fs, "%*snum_acts: %d\n", level, "", server->num_acts);
+ fprintf(fs, "%*ssize_acts: %d\n", level, "", server->size_acts);
+ if (server->acts != NULL) {
+ for (i = 0; i < server->num_acts; i++) {
+ fprintf(fs, "%*sacts[%d]:\n", level, "", i);
+ xkb_action_dump(fs, level + 2, pa++);
+ }
+ } else
+ fprintf(fs, "%*sNO acts\n", level, "");
- if( server->key_acts != NULL )
- {
- for( i = 0; i <= kbd->max_key_code; i++ )
- {
- fprintf( fs, "%*skey_acts[%d]: offset %d, total %d\n", level, "", i,
- server->key_acts[i], XkbKeyNumSyms(kbd,i) );
- }
- } else
- fprintf( fs, "%*sNO key_acts\n", level, "" );
+ if (server->key_acts != NULL) {
+ for (i = 0; i <= kbd->max_key_code; i++) {
+ fprintf(fs,
+ "%*skey_acts[%d]: offset %d, total %d\n",
+ level, "", i, server->key_acts[i],
+ XkbKeyNumSyms(kbd, i));
+ }
+ } else
+ fprintf(fs, "%*sNO key_acts\n", level, "");
- for( i = 0; i < XkbNumVirtualMods; i++ )
- {
- fprintf( fs, "%*svmod[%d]: %X\n", level, "", i, server->vmods[i] );
- }
+ for (i = 0; i < XkbNumVirtualMods; i++) {
+ fprintf(fs, "%*svmod[%d]: %X\n", level, "", i,
+ server->vmods[i]);
+ }
- if( server->behaviors != NULL )
- {
- for( i = 0; i <= kbd->max_key_code; i++ )
- {
- fprintf( fs, "%*sbehaviors[%d]:\n", level, "", i );
- _XkbBehaviorDump( fs, level + 2, pb++ );
- }
- } else
- fprintf( fs, "%*sNO behaviors\n", level, "" );
+ if (server->behaviors != NULL) {
+ for (i = 0; i <= kbd->max_key_code; i++) {
+ fprintf(fs, "%*sbehaviors[%d]:\n", level, "", i);
+ xkb_behavior_dump(fs, level + 2, pb++);
+ }
+ } else
+ fprintf(fs, "%*sNO behaviors\n", level, "");
- if( server->explicit != NULL )
- {
- for( i = 0; i <= kbd->max_key_code; i++ )
- {
- fprintf( fs, "%*sexplicit[%d]: %d\n", level, "", i,
- server->explicit[i] );
- }
- } else
- fprintf( fs, "%*sNO explicit\n", level, "" );
+ if (server->explicit != NULL) {
+ for (i = 0; i <= kbd->max_key_code; i++) {
+ fprintf(fs, "%*sexplicit[%d]: %d\n", level, "", i,
+ server->explicit[i]);
+ }
+ } else
+ fprintf(fs, "%*sNO explicit\n", level, "");
- if( server->vmodmap != NULL )
- {
- for( i = 0; i <= kbd->max_key_code; i++ )
- {
- fprintf( fs, "%*svmodmap[%d]: %d\n", level, "", i, server->vmodmap[i] );
- }
- } else
- fprintf( fs, "%*sNO vmodmap\n", level, "" );
+ if (server->vmodmap != NULL) {
+ for (i = 0; i <= kbd->max_key_code; i++) {
+ fprintf(fs, "%*svmodmap[%d]: %d\n", level, "", i,
+ server->vmodmap[i]);
+ }
+ } else
+ fprintf(fs, "%*sNO vmodmap\n", level, "");
}
-static void _XkbKeyTypeDump( FILE * fs, int level, XkbKeyTypePtr type )
+static void
+xkb_key_type_dump(FILE * fs, gint level, XkbKeyTypePtr type,
+ XklEngine * engine)
{
- char *z = type->name == None ? NULL : XGetAtomName( _xklDpy, type->name );
- fprintf( fs, "%*sname: 0x%X(%s)\n", level, "", (int)type->name, z );
- if( z != NULL )
- XFree( z );
+ gchar *z =
+ type->name ==
+ None ? NULL : XGetAtomName(xkl_engine_get_display(engine),
+ type->name);
+ fprintf(fs, "%*sname: 0x%X(%s)\n", level, "", (gint) type->name,
+ z);
+ if (z != NULL)
+ XFree(z);
}
-static void _XkbSymMapDump( FILE * fs, int level, XkbSymMapPtr ksm )
+static void
+xkb_sym_map_dump(FILE * fs, gint level, XkbSymMapPtr ksm)
{
- int i;
- fprintf( fs, "%*skt_index: ", level, "" );
- for( i = 0; i < XkbNumKbdGroups; i++ )
- {
- fprintf( fs, "%d ", ksm->kt_index[i] );
- }
- fprintf( fs, "\n%*sgroup_info: %d\n", level, "", ksm->group_info );
- fprintf( fs, "%*swidth: %d\n", level, "", ksm->width );
- fprintf( fs, "%*soffset: %d\n", level, "", ksm->offset );
+ gint i;
+ fprintf(fs, "%*skt_index: ", level, "");
+ for (i = 0; i < XkbNumKbdGroups; i++) {
+ fprintf(fs, "%d ", ksm->kt_index[i]);
+ }
+ fprintf(fs, "\n%*sgroup_info: %d\n", level, "", ksm->group_info);
+ fprintf(fs, "%*swidth: %d\n", level, "", ksm->width);
+ fprintf(fs, "%*soffset: %d\n", level, "", ksm->offset);
}
-static void _XkbClientMapDump( FILE * fs, int level, XkbClientMapPtr map,
- XkbDescPtr kbd )
+static void
+xkb_client_map_dump(FILE * fs, gint level, XkbClientMapPtr map,
+ XkbDescPtr kbd, XklEngine * engine)
{
- int i;
- fprintf( fs, "%*ssize_types: %d\n", level, "", map->size_types );
- fprintf( fs, "%*snum_types: %d\n", level, "", map->num_types );
- if( map->types != NULL )
- {
- XkbKeyTypePtr type = map->types;
- for( i = 0; i < map->num_types; i++ )
- {
- fprintf( fs, "%*stypes[%d]:\n", level, "", i );
- _XkbKeyTypeDump( fs, level + 2, type++ );
- }
- } else
- fprintf( fs, "%*sNO types\n", level, "" );
+ gint i;
+ fprintf(fs, "%*ssize_types: %d\n", level, "", map->size_types);
+ fprintf(fs, "%*snum_types: %d\n", level, "", map->num_types);
+ if (map->types != NULL) {
+ XkbKeyTypePtr type = map->types;
+ for (i = 0; i < map->num_types; i++) {
+ fprintf(fs, "%*stypes[%d]:\n", level, "", i);
+ xkb_key_type_dump(fs, level + 2, type++, engine);
+ }
+ } else
+ fprintf(fs, "%*sNO types\n", level, "");
- fprintf( fs, "%*ssize_syms: %d\n", level, "", map->size_syms );
- fprintf( fs, "%*snum_syms: %d\n", level, "", map->num_syms );
- if( map->syms != NULL )
- {
- for( i = 0; i < map->num_syms; i++ )
- fprintf( fs, "%*ssyms[%d]:0x%lX(%s)\n", level, "", i, map->syms[i],
- XKeysymToString( map->syms[i] ) );
- } else
- fprintf( fs, "%*sNO syms\n", level, "" );
- if( map->key_sym_map != NULL )
- {
- XkbSymMapPtr ksm = map->key_sym_map;
- for( i = 0; i <= kbd->max_key_code; i++ )
- {
- fprintf( fs, "%*skey_sym_map[%d]:\n", level, "", i );
- _XkbSymMapDump( fs, level + 2, ksm++ );
- }
- } else
- fprintf( fs, "%*sNO key_sym_map\n", level, "" );
+ fprintf(fs, "%*ssize_syms: %d\n", level, "", map->size_syms);
+ fprintf(fs, "%*snum_syms: %d\n", level, "", map->num_syms);
+ if (map->syms != NULL) {
+ for (i = 0; i < map->num_syms; i++)
+ fprintf(fs, "%*ssyms[%d]:0x%lX(%s)\n", level, "",
+ i, map->syms[i],
+ XKeysymToString(map->syms[i]));
+ } else
+ fprintf(fs, "%*sNO syms\n", level, "");
+ if (map->key_sym_map != NULL) {
+ XkbSymMapPtr ksm = map->key_sym_map;
+ for (i = 0; i <= kbd->max_key_code; i++) {
+ fprintf(fs, "%*skey_sym_map[%d]:\n", level, "", i);
+ xkb_sym_map_dump(fs, level + 2, ksm++);
+ }
+ } else
+ fprintf(fs, "%*sNO key_sym_map\n", level, "");
}
-static void _XkbDescDump( FILE * fs, int level, XkbDescPtr kbd )
+static void
+xkb_desc_dump(FILE * fs, gint level, XkbDescPtr kbd, XklEngine * engine)
{
- fprintf( fs, "%*sflags: 0x%X\n", level, "", kbd->flags );
- fprintf( fs, "%*sdevice_spec: %d\n", level, "", kbd->device_spec );
- fprintf( fs, "%*smin_key_code: %d\n", level, "", kbd->min_key_code );
- fprintf( fs, "%*smax_key_code: %d\n", level, "", kbd->max_key_code );
+ fprintf(fs, "%*sflags: 0x%X\n", level, "", kbd->flags);
+ fprintf(fs, "%*sdevice_spec: %d\n", level, "", kbd->device_spec);
+ fprintf(fs, "%*smin_key_code: %d\n", level, "", kbd->min_key_code);
+ fprintf(fs, "%*smax_key_code: %d\n", level, "", kbd->max_key_code);
#if 0
- if( kbd->ctrls != NULL )
- {
- fprintf( fs, "ctrls:\n" );
- _XkbControlsDump( fs, kbd->ctrls );
- } else
- fprintf( fs, "NO server\n" );
+ if (kbd->ctrls != NULL) {
+ fprintf(fs, "ctrls:\n");
+ _XkbControlsDump(fs, kbd->ctrls);
+ } else
+ fprintf(fs, "NO server\n");
#endif
- if( kbd->server != NULL )
- {
- fprintf( fs, "%*sserver:\n", level, "" );
- _XkbServerMapDump( fs, level + 2, kbd->server, kbd );
- } else
- fprintf( fs, "%*sNO server\n", level, "" );
+ if (kbd->server != NULL) {
+ fprintf(fs, "%*sserver:\n", level, "");
+ xkb_server_map_dump(fs, level + 2, kbd->server, kbd);
+ } else
+ fprintf(fs, "%*sNO server\n", level, "");
- if( kbd->map != NULL )
- {
- fprintf( fs, "%*smap:\n", level, "" );
- _XkbClientMapDump( fs, level + 2, kbd->map, kbd );
- } else
- fprintf( fs, "%*sNO map\n", level, "" );
- fprintf( fs, "XKB libraries not present\n" );
+ if (kbd->map != NULL) {
+ fprintf(fs, "%*smap:\n", level, "");
+ xkb_client_map_dump(fs, level + 2, kbd->map, kbd, engine);
+ } else
+ fprintf(fs, "%*sNO map\n", level, "");
+ fprintf(fs, "XKB libraries not present\n");
}
-void XklDumpXkbDesc( const char *filename, XkbDescPtr kbd )
+void
+xkl_engine_dump_xkb_desc(XklEngine * engine, const gchar * file_name,
+ XkbDescPtr kbd)
{
- FILE *fs = fopen( filename, "w+" );
- if( fs != NULL )
- {
- _XkbDescDump( fs, 0, kbd == NULL ? _xklXkb : kbd );
- fclose( fs );
- }
+ FILE *fs = fopen(file_name, "w+");
+ if (fs != NULL) {
+ xkb_desc_dump(fs, 0,
+ kbd == NULL ? xkl_engine_backend(engine,
+ XklXkb,
+ cached_desc)
+ : kbd, engine);
+ fclose(fs);
+ }
}
#endif
diff --git a/libxklavier/xklavier_evt.c b/libxklavier/xklavier_evt.c
index 1540841..40dd41a 100644
--- a/libxklavier/xklavier_evt.c
+++ b/libxklavier/xklavier_evt.c
@@ -1,327 +1,433 @@
+#include <string.h>
#include <time.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <X11/Xlibint.h>
#include "xklavier_private.h"
-int XklFilterEvents( XEvent * xev )
+gint
+xkl_engine_filter_events(XklEngine * engine, XEvent * xev)
{
- XAnyEvent *pe = ( XAnyEvent * ) xev;
- XklDebug( 400, "**> Filtering event %d of type %d from window %d\n",
- pe->serial, pe->type, pe->window );
- _XklEnsureVTableInited();
- if ( !xklVTable->xklEventHandler( xev ) )
- switch ( xev->type )
- { /* core events */
- case FocusIn:
- _XklFocusInEvHandler( &xev->xfocus );
- break;
- case FocusOut:
- _XklFocusOutEvHandler( &xev->xfocus );
- break;
- case PropertyNotify:
- _XklPropertyEvHandler( &xev->xproperty );
- break;
- case CreateNotify:
- _XklCreateEvHandler( &xev->xcreatewindow );
- break;
- case DestroyNotify:
- XklDebug( 150, "Window " WINID_FORMAT " destroyed\n",
- xev->xdestroywindow.window );
- break;
- case UnmapNotify:
- XklDebug( 200, "Window " WINID_FORMAT " unmapped\n",
- xev->xunmap.window );
- break;
- case MapNotify:
- XklDebug( 200, "%s\n", _XklGetEventName( xev->type ) );
- break;
- case MappingNotify:
- XklDebug( 200, "%s\n", _XklGetEventName( xev->type ) );
- _XklResetAllInfo( "X event: MappingNotify" );
- break;
- case GravityNotify:
- XklDebug( 200, "%s\n", _XklGetEventName( xev->type ) );
- break;
- case ReparentNotify:
- XklDebug( 200, "Window " WINID_FORMAT " reparented to " WINID_FORMAT "\n",
- xev->xreparent.window, xev->xreparent.parent );
- break;
- default:
- {
- XklDebug( 200, "Unknown event %d [%s]\n",
- xev->type, _XklGetEventName( xev->type ) );
- return 1;
- }
- }
- XklDebug( 400, "Filtered event %d of type %d from window %d **>\n",
- pe->serial, pe->type, pe->window );
- return 1;
+ XAnyEvent *pe = (XAnyEvent *) xev;
+ xkl_debug(400,
+ "**> Filtering event %d of type %d from window %d\n",
+ pe->serial, pe->type, pe->window);
+ xkl_engine_ensure_vtable_inited(engine);
+ if (!xkl_engine_vcall(engine, process_x_event) (engine, xev))
+ switch (xev->type) { /* core events */
+ case FocusIn:
+ xkl_engine_process_focus_in_evt(engine,
+ &xev->xfocus);
+ break;
+ case FocusOut:
+ xkl_engine_process_focus_out_evt(engine,
+ &xev->xfocus);
+ break;
+ case PropertyNotify:
+ xkl_engine_process_property_evt(engine,
+ &xev->xproperty);
+ break;
+ case CreateNotify:
+ xkl_engine_process_create_window_evt(engine,
+ &xev->
+ xcreatewindow);
+ break;
+ case DestroyNotify:
+ xkl_debug(150,
+ "Window " WINID_FORMAT " destroyed\n",
+ xev->xdestroywindow.window);
+ break;
+ case UnmapNotify:
+ xkl_debug(200,
+ "Window " WINID_FORMAT " unmapped\n",
+ xev->xunmap.window);
+ break;
+ case MapNotify:
+ case GravityNotify:
+ xkl_debug(200, "%s\n",
+ xkl_event_get_name(xev->type));
+ break; /* Ignore these events */
+ case ReparentNotify:
+ xkl_debug(200,
+ "Window " WINID_FORMAT " reparented to "
+ WINID_FORMAT "\n", xev->xreparent.window,
+ xev->xreparent.parent);
+ break; /* Ignore these events */
+ case MappingNotify:
+ xkl_debug(200, "%s\n",
+ xkl_event_get_name(xev->type));
+ xkl_engine_reset_all_info(engine,
+ "X event: MappingNotify");
+ break;
+ default:
+ {
+ xkl_debug(200, "Unknown event %d [%s]\n",
+ xev->type,
+ xkl_event_get_name(xev->type));
+ return 1;
+ }
+ }
+ xkl_debug(400, "Filtered event %d of type %d from window %d **>\n",
+ pe->serial, pe->type, pe->window);
+ return 1;
}
-/**
+/*
* FocusIn handler
*/
-void _XklFocusInEvHandler( XFocusChangeEvent * fev )
+void
+xkl_engine_process_focus_in_evt(XklEngine * engine,
+ XFocusChangeEvent * fev)
{
- Window win;
- Window appWin;
- XklState selectedWindowState;
-
- if( !( _xklListenerType & XKLL_MANAGE_WINDOW_STATES ) )
- return;
-
- win = fev->window;
-
- switch ( fev->mode )
- {
- case NotifyNormal:
- case NotifyWhileGrabbed:
- break;
- default:
- XklDebug( 160,
- "Window " WINID_FORMAT
- " has got focus during special action %d\n", win, fev->mode );
- return;
- }
-
- XklDebug( 150, "Window " WINID_FORMAT ", '%s' has got focus\n", win,
- _XklGetDebugWindowTitle( win ) );
-
- if( !_XklGetAppWindow( win, &appWin ) )
- {
- return;
- }
-
- XklDebug( 150, "Appwin " WINID_FORMAT ", '%s' has got focus\n", appWin,
- _XklGetDebugWindowTitle( appWin ) );
-
- if( XklGetState( appWin, &selectedWindowState ) )
- {
- if( _xklCurClient != appWin )
- {
- Bool oldWinTransparent, newWinTransparent;
- XklState tmpState;
-
- oldWinTransparent = _XklIsTransparentAppWindow( _xklCurClient );
- if( oldWinTransparent )
- XklDebug( 150, "Leaving transparent window\n" );
-
- /**
- * Reload the current state from the current window.
- * Do not do it for transparent window - we keep the state from
- * the _previous_ window.
- */
- if ( !oldWinTransparent && XklGetState ( _xklCurClient, &tmpState ) )
- {
- _XklUpdateCurState( tmpState.group,
- tmpState.indicators,
- "Loading current (previous) state from the current (previous) window" );
- }
-
- _xklCurClient = appWin;
- XklDebug( 150, "CurClient:changed to " WINID_FORMAT ", '%s'\n",
- _xklCurClient, _XklGetDebugWindowTitle( _xklCurClient ) );
-
- newWinTransparent = _XklIsTransparentAppWindow( appWin );
- if( newWinTransparent )
- XklDebug( 150, "Entering transparent window\n" );
-
- if( XklIsGroupPerApp() == !newWinTransparent )
- {
- /* We skip restoration only if we return to the same app window */
- Bool doSkip = False;
- if( _xklSkipOneRestore )
- {
- _xklSkipOneRestore = False;
- if( appWin == _xklPrevAppWindow )
- doSkip = True;
- }
-
- if( doSkip )
- {
- XklDebug( 150,
- "Skipping one restore as requested - instead, saving the current group into the window state\n" );
- _XklSaveAppState( appWin, &_xklCurState );
- } else
- {
- if( _xklCurState.group != selectedWindowState.group )
- {
- XklDebug( 150,
- "Restoring the group from %d to %d after gaining focus\n",
- _xklCurState.group, selectedWindowState.group );
- /**
- * For fast mouse movements - the state is probably not updated yet
- * (because of the group change notification being late).
- * so we'll enforce the update. But this should only happen in GPA mode
- */
- _XklUpdateCurState( selectedWindowState.group,
- selectedWindowState.indicators,
- "Enforcing fast update of the current state" );
- XklLockGroup( selectedWindowState.group );
- } else
- {
- XklDebug( 150,
- "Both old and new focused window have group %d so no point restoring it\n",
- selectedWindowState.group );
- _XklOneSwitchToSecondaryGroupPerformed();
- }
- }
-
- if( ( xklVTable->features & XKLF_CAN_TOGGLE_INDICATORS ) &&
- XklGetIndicatorsHandling( ) )
- {
- XklDebug( 150,
- "Restoring the indicators from %X to %X after gaining focus\n",
- _xklCurState.indicators, selectedWindowState.indicators );
- _XklEnsureVTableInited();
- (*xklVTable->xklSetIndicatorsHandler)( &selectedWindowState );
- } else
- XklDebug( 150,
- "Not restoring the indicators %X after gaining focus: indicator handling is not enabled\n",
- _xklCurState.indicators );
- } else
- XklDebug( 150,
- "Not restoring the group %d after gaining focus: global layout (xor transparent window)\n",
- _xklCurState.group );
- } else
- XklDebug( 150, "Same app window - just do nothing\n" );
- } else
- {
- XklDebug( 150, "But it does not have xklavier_state\n" );
- if( _XklHasWmState( win ) )
- {
- XklDebug( 150, "But it does have wm_state so we'll add it\n" );
- _xklCurClient = appWin;
- XklDebug( 150, "CurClient:changed to " WINID_FORMAT ", '%s'\n",
- _xklCurClient, _XklGetDebugWindowTitle( _xklCurClient ) );
- _XklAddAppWindow( _xklCurClient, ( Window ) NULL, False,
- &_xklCurState );
- } else
- XklDebug( 150, "And it does have wm_state either\n" );
- }
+ Window win;
+ Window toplevel_win;
+ XklState selected_window_state;
+
+ if (!
+ (xkl_engine_priv(engine, listener_type) &
+ XKLL_MANAGE_WINDOW_STATES))
+ return;
+
+ win = fev->window;
+
+ switch (fev->mode) {
+ case NotifyNormal:
+ case NotifyWhileGrabbed:
+ break;
+ default:
+ xkl_debug(160,
+ "Window " WINID_FORMAT
+ " has got focus during special action %d\n", win,
+ fev->mode);
+ return;
+ }
+
+ xkl_debug(150, "Window " WINID_FORMAT ", '%s' has got focus\n",
+ win, xkl_get_debug_window_title(engine, win));
+
+ if (!xkl_engine_find_toplevel_window(engine, win, &toplevel_win)) {
+ return;
+ }
+
+ xkl_debug(150, "Appwin " WINID_FORMAT ", '%s' has got focus\n",
+ toplevel_win, xkl_get_debug_window_title(engine,
+ toplevel_win));
+
+ if (xkl_engine_get_toplevel_window_state
+ (engine, toplevel_win, &selected_window_state)) {
+ if (xkl_engine_priv(engine, curr_toplvl_win) !=
+ toplevel_win) {
+ gboolean old_win_transparent, new_win_transparent;
+ XklState tmp_state;
+
+ old_win_transparent =
+ xkl_engine_is_toplevel_window_transparent
+ (engine,
+ xkl_engine_priv(engine, curr_toplvl_win));
+ if (old_win_transparent)
+ xkl_debug(150,
+ "Leaving transparent window\n");
+
+ /*
+ * Reload the current state from the current window.
+ * Do not do it for transparent window - we keep the state from
+ * the _previous_ window.
+ */
+ if (!old_win_transparent &&
+ xkl_engine_get_toplevel_window_state(engine,
+ xkl_engine_priv
+ (engine,
+ curr_toplvl_win),
+ &tmp_state))
+ {
+ xkl_engine_update_current_state(engine,
+ tmp_state.
+ group,
+ tmp_state.
+ indicators,
+ "Loading current (previous) state from the current (previous) window");
+ }
+
+ xkl_engine_priv(engine, curr_toplvl_win) =
+ toplevel_win;
+ xkl_debug(150,
+ "CurClient:changed to " WINID_FORMAT
+ ", '%s'\n", xkl_engine_priv(engine,
+ curr_toplvl_win),
+ xkl_get_debug_window_title(engine,
+ xkl_engine_priv
+ (engine,
+ curr_toplvl_win)));
+
+ new_win_transparent =
+ xkl_engine_is_toplevel_window_transparent
+ (engine, toplevel_win);
+ if (new_win_transparent)
+ xkl_debug(150,
+ "Entering transparent window\n");
+
+ if (xkl_engine_is_group_per_toplevel_window(engine)
+ == !new_win_transparent) {
+ /* We skip restoration only if we return to the same app window */
+ gboolean do_skip = FALSE;
+ if (xkl_engine_priv
+ (engine, skip_one_restore)) {
+ xkl_engine_priv(engine,
+ skip_one_restore) =
+ FALSE;
+ if (toplevel_win ==
+ xkl_engine_priv(engine,
+ prev_toplvl_win))
+ do_skip = TRUE;
+ }
+
+ if (do_skip) {
+ xkl_debug(150,
+ "Skipping one restore as requested - instead, "
+ "saving the current group into the window state\n");
+ xkl_engine_save_toplevel_window_state
+ (engine, toplevel_win,
+ &xkl_engine_priv(engine,
+ curr_state));
+ } else {
+ if (xkl_engine_priv
+ (engine,
+ curr_state).group !=
+ selected_window_state.group) {
+ xkl_debug(150,
+ "Restoring the group from %d to %d after gaining focus\n",
+ xkl_engine_priv
+ (engine,
+ curr_state).
+ group,
+ selected_window_state.
+ group);
+ /*
+ * For fast mouse movements - the state is probably not updated yet
+ * (because of the group change notification being late).
+ * so we'll enforce the update. But this should only happen in GPA mode
+ */
+ xkl_engine_update_current_state
+ (engine,
+ selected_window_state.
+ group,
+ selected_window_state.
+ indicators,
+ "Enforcing fast update of the current state");
+ xkl_engine_lock_group
+ (engine,
+ selected_window_state.
+ group);
+ } else {
+ xkl_debug(150,
+ "Both old and new focused window "
+ "have group %d so no point restoring it\n",
+ selected_window_state.
+ group);
+ xkl_engine_one_switch_to_secondary_group_performed
+ (engine);
+ }
+ }
+
+ if ((xkl_engine_priv(engine, features) &
+ XKLF_CAN_TOGGLE_INDICATORS)
+ &&
+ xkl_engine_get_indicators_handling
+ (engine)) {
+ xkl_debug(150,
+ "Restoring the indicators from %X to %X after gaining focus\n",
+ xkl_engine_priv(engine,
+ curr_state).
+ indicators,
+ selected_window_state.
+ indicators);
+ xkl_engine_ensure_vtable_inited
+ (engine);
+ xkl_engine_vcall(engine,
+ set_indicators)
+ (engine,
+ &selected_window_state);
+ } else
+ xkl_debug(150,
+ "Not restoring the indicators %X after gaining focus: indicator handling is not enabled\n",
+ xkl_engine_priv(engine,
+ curr_state).
+ indicators);
+ } else
+ xkl_debug(150,
+ "Not restoring the group %d after gaining focus: global layout (xor transparent window)\n",
+ xkl_engine_priv(engine,
+ curr_state).
+ group);
+ } else
+ xkl_debug(150,
+ "Same app window - just do nothing\n");
+ } else {
+ xkl_debug(150, "But it does not have xklavier_state\n");
+ if (xkl_engine_if_window_has_wm_state(engine, win)) {
+ xkl_debug(150,
+ "But it does have wm_state so we'll add it\n");
+ xkl_engine_priv(engine, curr_toplvl_win) =
+ toplevel_win;
+ xkl_debug(150,
+ "CurClient:changed to " WINID_FORMAT
+ ", '%s'\n", xkl_engine_priv(engine,
+ curr_toplvl_win),
+ xkl_get_debug_window_title(engine,
+ xkl_engine_priv
+ (engine,
+ curr_toplvl_win)));
+ xkl_engine_add_toplevel_window(engine,
+ xkl_engine_priv
+ (engine,
+ curr_toplvl_win),
+ (Window) NULL,
+ FALSE,
+ &xkl_engine_priv
+ (engine,
+ curr_state));
+ } else
+ xkl_debug(150,
+ "And it does have wm_state either\n");
+ }
}
-/**
+/*
* FocusOut handler
*/
-void _XklFocusOutEvHandler( XFocusChangeEvent * fev )
+void
+xkl_engine_process_focus_out_evt(XklEngine * engine,
+ XFocusChangeEvent * fev)
{
- if( !( _xklListenerType & XKLL_MANAGE_WINDOW_STATES ) )
- return;
-
- if( fev->mode != NotifyNormal )
- {
- XklDebug( 200,
- "Window " WINID_FORMAT
- " has lost focus during special action %d\n", fev->window,
- fev->mode );
- return;
- }
-
- XklDebug( 160, "Window " WINID_FORMAT ", '%s' has lost focus\n",
- fev->window, _XklGetDebugWindowTitle( fev->window ) );
-
- if( XklIsTransparent( fev->window ) )
- {
-
- XklDebug( 150, "Leaving transparent window!\n" );
-/**
+ if (!
+ (xkl_engine_priv(engine, listener_type) &
+ XKLL_MANAGE_WINDOW_STATES))
+ return;
+
+ if (fev->mode != NotifyNormal) {
+ xkl_debug(200,
+ "Window " WINID_FORMAT
+ " has lost focus during special action %d\n",
+ fev->window, fev->mode);
+ return;
+ }
+
+ xkl_debug(160, "Window " WINID_FORMAT ", '%s' has lost focus\n",
+ fev->window, xkl_get_debug_window_title(engine,
+ fev->window));
+
+ if (xkl_engine_is_window_transparent(engine, fev->window)) {
+ xkl_debug(150, "Leaving transparent window!\n");
+/*
* If we are leaving the transparent window - we skip the restore operation.
* This is useful for secondary groups switching from the transparent control
* window.
*/
- _xklSkipOneRestore = True;
- } else
- {
- Window p;
- if( _XklGetAppWindow( fev->window, &p ) )
- _xklPrevAppWindow = p;
- }
+ xkl_engine_priv(engine, skip_one_restore) = TRUE;
+ } else {
+ Window p;
+ if (xkl_engine_find_toplevel_window
+ (engine, fev->window, &p))
+ xkl_engine_priv(engine, prev_toplvl_win) = p;
+ }
}
-/**
+/*
* PropertyChange handler
* Interested in :
* + for XKLL_MANAGE_WINDOW_STATES
* - WM_STATE property for all windows
* - Configuration property of the root window
*/
-void _XklPropertyEvHandler( XPropertyEvent * pev )
+void
+xkl_engine_process_property_evt(XklEngine * engine, XPropertyEvent * pev)
{
- if( 400 <= _xklDebugLevel )
- {
- char *atomName = XGetAtomName( _xklDpy, pev->atom );
- if( atomName != NULL )
- {
- XklDebug( 400, "The property '%s' changed for " WINID_FORMAT "\n",
- atomName, pev->window );
- XFree( atomName );
- } else
- {
- XklDebug( 200, "Some magic property changed for " WINID_FORMAT "\n",
- pev->window );
- }
- }
-
- if( _xklListenerType & XKLL_MANAGE_WINDOW_STATES )
- {
- if( pev->atom == _xklAtoms[WM_STATE] )
- {
- Bool hasXklState = XklGetState( pev->window, NULL );
-
- if( pev->state == PropertyNewValue )
- {
- XklDebug( 160, "New value of WM_STATE on window " WINID_FORMAT "\n",
- pev->window );
- if( !hasXklState ) /* Is this event the first or not? */
- {
- _XklAddAppWindow( pev->window, ( Window ) NULL, False,
- &_xklCurState );
- }
- } else
- { /* ev->xproperty.state == PropertyDelete, either client or WM can remove it, ICCCM 4.1.3.1 */
- XklDebug( 160, "Something (%d) happened to WM_STATE of window 0x%x\n",
- pev->state, pev->window );
- _XklSelectInputMerging( pev->window, PropertyChangeMask );
- if( hasXklState )
- {
- XklDelState( pev->window );
- }
- }
- } else
- if( pev->atom == xklVTable->baseConfigAtom
- && pev->window == _xklRootWindow )
- {
- if( pev->state == PropertyNewValue )
- {
- /* If root window got new *_NAMES_PROP_ATOM -
- it most probably means new keyboard config is loaded by somebody */
- _XklResetAllInfo( "New value of *_NAMES_PROP_ATOM on root window" );
- }
- }
- } /* XKLL_MANAGE_WINDOW_STATES */
+ if (400 <= xkl_debug_level) {
+ char *atom_name =
+ XGetAtomName(xkl_engine_get_display(engine),
+ pev->atom);
+ if (atom_name != NULL) {
+ xkl_debug(400,
+ "The property '%s' changed for "
+ WINID_FORMAT "\n", atom_name,
+ pev->window);
+ XFree(atom_name);
+ } else {
+ xkl_debug(200,
+ "Some magic property changed for "
+ WINID_FORMAT "\n", pev->window);
+ }
+ }
+
+ if (xkl_engine_priv(engine, listener_type) &
+ XKLL_MANAGE_WINDOW_STATES) {
+ if (pev->atom == xkl_engine_priv(engine, atoms)[WM_STATE]) {
+ gboolean has_xkl_state =
+ xkl_engine_get_state(engine, pev->window,
+ NULL);
+
+ if (pev->state == PropertyNewValue) {
+ xkl_debug(160,
+ "New value of WM_STATE on window "
+ WINID_FORMAT "\n", pev->window);
+ if (!has_xkl_state) { /* Is this event the first or not? */
+ xkl_engine_add_toplevel_window
+ (engine, pev->window, (Window)
+ NULL, FALSE,
+ &xkl_engine_priv(engine,
+ curr_state));
+ }
+ } else { /* ev->xproperty.state == PropertyDelete, either client or WM can remove it, ICCCM 4.1.3.1 */
+ xkl_debug(160,
+ "Something (%d) happened to WM_STATE of window 0x%x\n",
+ pev->state, pev->window);
+ xkl_engine_select_input_merging(engine,
+ pev->
+ window,
+ PropertyChangeMask);
+ if (has_xkl_state) {
+ xkl_engine_delete_state(engine,
+ pev->
+ window);
+ }
+ }
+ } else
+ if (pev->atom ==
+ xkl_engine_priv(engine, base_config_atom)
+ && pev->window == xkl_engine_priv(engine,
+ root_window)) {
+ if (pev->state == PropertyNewValue) {
+ /* If root window got new *_NAMES_PROP_ATOM -
+ it most probably means new keyboard config is loaded by somebody */
+ xkl_engine_reset_all_info
+ (engine,
+ "New value of *_NAMES_PROP_ATOM on root window");
+ }
+ }
+ } /* XKLL_MANAGE_WINDOW_STATES */
}
-/**
+/*
* CreateNotify handler. Just interested in properties and focus events...
*/
-void _XklCreateEvHandler( XCreateWindowEvent * cev )
+void
+xkl_engine_process_create_window_evt(XklEngine * engine,
+ XCreateWindowEvent * cev)
{
- if( !( _xklListenerType & XKLL_MANAGE_WINDOW_STATES ) )
- return;
-
- XklDebug( 200,
- "Under-root window " WINID_FORMAT
- "/%s (%d,%d,%d x %d) is created\n", cev->window,
- _XklGetDebugWindowTitle( cev->window ), cev->x, cev->y,
- cev->width, cev->height );
-
- if( !cev->override_redirect )
- {
+ if (!
+ (xkl_engine_priv(engine, listener_type) &
+ XKLL_MANAGE_WINDOW_STATES))
+ return;
+
+ xkl_debug(200,
+ "Under-root window " WINID_FORMAT
+ "/%s (%d,%d,%d x %d) is created\n", cev->window,
+ xkl_get_debug_window_title(engine, cev->window), cev->x,
+ cev->y, cev->width, cev->height);
+
+ if (!cev->override_redirect) {
/* ICCCM 4.1.6: override-redirect is NOT private to
* client (and must not be changed - am I right?)
* We really need only PropertyChangeMask on this window but even in the case of
@@ -329,126 +435,173 @@ void _XklCreateEvHandler( XCreateWindowEvent * cev )
* event + SelectInput request is not zero) and we definitely will (my system DO)
* lose FocusIn/Out events after the following call of PropertyNotifyHandler.
* So I just decided to purify this extra FocusChangeMask in the FocusIn/OutHandler. */
- _XklSelectInputMerging( cev->window,
- PropertyChangeMask | FocusChangeMask );
-
- if( _XklHasWmState( cev->window ) )
- {
- XklDebug( 200,
- "Just created window already has WM_STATE - so I'll add it" );
- _XklAddAppWindow( cev->window, ( Window ) NULL, False, &_xklCurState );
- }
- }
+ xkl_engine_select_input_merging(engine, cev->window,
+ PropertyChangeMask |
+ FocusChangeMask);
+
+ if (xkl_engine_if_window_has_wm_state(engine, cev->window)) {
+ xkl_debug(200,
+ "Just created window already has WM_STATE - so I'll add it");
+ xkl_engine_add_toplevel_window(engine, cev->window,
+ (Window) NULL,
+ FALSE,
+ &xkl_engine_priv
+ (engine,
+ curr_state));
+ }
+ }
}
-/**
+/*
* Just error handler - sometimes we get BadWindow error for already gone
* windows, so we'll just ignore
*/
-void _XklErrHandler( Display * dpy, XErrorEvent * evt )
+void
+xkl_process_error(Display * dpy, XErrorEvent * evt)
{
- char buf[128] = "";
- _xklLastErrorCode = evt->error_code;
- switch ( _xklLastErrorCode )
- {
- case BadWindow:
- case BadAccess:
- {
- XGetErrorText( dpy, _xklLastErrorCode, buf, sizeof(buf) );
- /* in most cases this means we are late:) */
- XklDebug( 200, "ERROR: %p, " WINID_FORMAT ", %d [%s], "
- "X11 request: %d, minor code: %d\n",
- dpy,
- ( unsigned long ) evt->resourceid,
- ( int ) evt->error_code, buf,
- ( int ) evt->request_code,
- ( int ) evt->minor_code );
- break;
- }
- default:
- ( *_xklDefaultErrHandler ) ( dpy, evt );
- }
+ char buf[128] = "";
+ XklEngine *engine = xkl_get_the_engine();
+
+ xkl_engine_priv(engine, last_error_code) = evt->error_code;
+ switch (xkl_engine_priv(engine, last_error_code)) {
+ case BadWindow:
+ case BadAccess:
+ {
+ XGetErrorText(xkl_engine_get_display(engine),
+ evt->error_code, buf,
+ sizeof(buf));
+ /* in most cases this means we are late:) */
+ xkl_debug(200,
+ "ERROR: %p, " WINID_FORMAT ", %d [%s], "
+ "X11 request: %d, minor code: %d\n", dpy,
+ (unsigned long) evt->resourceid,
+ (int) evt->error_code, buf,
+ (int) evt->request_code,
+ (int) evt->minor_code);
+ break;
+ }
+ default:
+ (*xkl_engine_priv(engine, default_error_handler)) (dpy,
+ evt);
+ }
}
-/**
+/*
* Some common functionality for Xkb handler
*/
-void _XklStateModificationHandler( XklStateChange changeType,
- int grp,
- unsigned inds,
- Bool setInds )
+void
+xkl_engine_process_state_modification(XklEngine * engine,
+ XklEngineStateChange change_type,
+ gint grp, guint inds,
+ gboolean set_inds)
{
- Window focused, focusedApp;
- XklState oldState;
- int revert;
- Bool haveOldState = True;
- Bool setGroup = changeType == GROUP_CHANGED;
-
- XGetInputFocus( _xklDpy, &focused, &revert );
-
- if( ( focused == None ) || ( focused == PointerRoot ) )
- {
- XklDebug( 160, "Something with focus: " WINID_FORMAT "\n", focused );
- return;
- }
-
- /**
- * Only if we manage states - otherwise _xklCurClient does not make sense
- */
- if( !_XklGetAppWindow( focused, &focusedApp ) &&
- _xklListenerType & XKLL_MANAGE_WINDOW_STATES )
- focusedApp = _xklCurClient; /* what else can I do */
-
- XklDebug( 150, "Focused window: " WINID_FORMAT ", '%s'\n", focusedApp,
- _XklGetDebugWindowTitle( focusedApp ) );
- if( _xklListenerType & XKLL_MANAGE_WINDOW_STATES )
- {
- XklDebug( 150, "CurClient: " WINID_FORMAT ", '%s'\n", _xklCurClient,
- _XklGetDebugWindowTitle( _xklCurClient ) );
-
- if( focusedApp != _xklCurClient )
- {
- /**
- * If not state - we got the new window
- */
- if ( !_XklGetAppState( focusedApp, &oldState ) )
- {
- _XklUpdateCurState( grp, inds,
- "Updating the state from new focused window" );
- if( _xklListenerType & XKLL_MANAGE_WINDOW_STATES )
- _XklAddAppWindow( focusedApp, ( Window ) NULL, False, &_xklCurState );
- }
- /**
- * There is state - just get the state from the window
- */
- else
- {
- grp = oldState.group;
- inds = oldState.indicators;
- }
- _xklCurClient = focusedApp;
- XklDebug( 160, "CurClient:changed to " WINID_FORMAT ", '%s'\n",
- _xklCurClient, _XklGetDebugWindowTitle( _xklCurClient ) );
- }
- /* If the window already has this this state - we are just restoring it!
- (see the second parameter of stateCallback */
- haveOldState = _XklGetAppState( _xklCurClient, &oldState );
- } else /* just tracking the stuff, no smart things */
- {
- XklDebug( 160, "Just updating the current state in the tracking mode\n" );
- memcpy( &oldState, &_xklCurState, sizeof( XklState ) );
- }
-
- if( setGroup || haveOldState )
- {
- _XklUpdateCurState( setGroup ? grp : oldState.group,
- setInds ? inds : oldState.indicators,
- "Restoring the state from the window" );
- }
-
- if( haveOldState )
- _XklTryCallStateCallback( changeType, &oldState );
-
- if( _xklListenerType & XKLL_MANAGE_WINDOW_STATES )
- _XklSaveAppState( _xklCurClient, &_xklCurState );
+ Window focused, focused_toplevel;
+ XklState old_state;
+ gint revert;
+ gboolean have_old_state = TRUE;
+ gboolean set_group = change_type == GROUP_CHANGED;
+
+ XGetInputFocus(xkl_engine_get_display(engine), &focused, &revert);
+
+ if ((focused == None) || (focused == PointerRoot)) {
+ xkl_debug(160, "Something with focus: " WINID_FORMAT "\n",
+ focused);
+ return;
+ }
+
+ /*
+ * Only if we manage states - otherwise xkl_engine_priv(engine,curr_toplvl_win) does not make sense
+ */
+ if (!xkl_engine_find_toplevel_window
+ (engine, focused, &focused_toplevel)
+ && xkl_engine_priv(engine,
+ listener_type) & XKLL_MANAGE_WINDOW_STATES)
+ focused_toplevel = xkl_engine_priv(engine, curr_toplvl_win); /* what else can I do */
+
+ xkl_debug(150, "Focused window: " WINID_FORMAT ", '%s'\n",
+ focused_toplevel,
+ xkl_get_debug_window_title(engine, focused_toplevel));
+ if (xkl_engine_priv(engine, listener_type) &
+ XKLL_MANAGE_WINDOW_STATES) {
+ xkl_debug(150, "CurClient: " WINID_FORMAT ", '%s'\n",
+ xkl_engine_priv(engine, curr_toplvl_win),
+ xkl_get_debug_window_title(engine,
+ xkl_engine_priv
+ (engine,
+ curr_toplvl_win)));
+
+ if (focused_toplevel !=
+ xkl_engine_priv(engine, curr_toplvl_win)) {
+ /*
+ * If not state - we got the new window
+ */
+ if (!xkl_engine_get_toplevel_window_state
+ (engine, focused_toplevel, &old_state)) {
+ xkl_engine_update_current_state(engine,
+ grp, inds,
+ "Updating the state from new focused window");
+ if (xkl_engine_priv(engine, listener_type)
+ & XKLL_MANAGE_WINDOW_STATES)
+ xkl_engine_add_toplevel_window
+ (engine, focused_toplevel,
+ (Window) NULL, FALSE,
+ &xkl_engine_priv(engine,
+ curr_state));
+ }
+ /*
+ * There is state - just get the state from the window
+ */
+ else {
+ grp = old_state.group;
+ inds = old_state.indicators;
+ }
+ xkl_engine_priv(engine, curr_toplvl_win) =
+ focused_toplevel;
+ xkl_debug(160,
+ "CurClient:changed to " WINID_FORMAT
+ ", '%s'\n", xkl_engine_priv(engine,
+ curr_toplvl_win),
+ xkl_get_debug_window_title(engine,
+ xkl_engine_priv
+ (engine,
+ curr_toplvl_win)));
+ }
+ /* If the window already has this this state - we are just restoring it!
+ (see the second parameter of stateCallback */
+ have_old_state =
+ xkl_engine_get_toplevel_window_state(engine,
+ xkl_engine_priv
+ (engine,
+ curr_toplvl_win),
+ &old_state);
+ } else { /* just tracking the stuff, no smart things */
+
+ xkl_debug(160,
+ "Just updating the current state in the tracking mode\n");
+ memcpy(&old_state, &xkl_engine_priv(engine, curr_state),
+ sizeof(XklState));
+ }
+
+ if (set_group || have_old_state) {
+ xkl_engine_update_current_state(engine,
+ set_group ? grp :
+ old_state.group,
+ set_inds ? inds :
+ old_state.indicators,
+ "Restoring the state from the window");
+ }
+
+ if (have_old_state)
+ xkl_engine_try_call_state_func(engine, change_type,
+ &old_state);
+
+ if (xkl_engine_priv(engine, listener_type) &
+ XKLL_MANAGE_WINDOW_STATES)
+ xkl_engine_save_toplevel_window_state(engine,
+ xkl_engine_priv
+ (engine,
+ curr_toplvl_win),
+ &xkl_engine_priv
+ (engine,
+ curr_state));
}
diff --git a/libxklavier/xklavier_evt_xkb.c b/libxklavier/xklavier_evt_xkb.c
index d70a3a3..19da8e3 100644
--- a/libxklavier/xklavier_evt_xkb.c
+++ b/libxklavier/xklavier_evt_xkb.c
@@ -3,135 +3,141 @@
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <X11/Xlibint.h>
#include "xklavier_private.h"
#include "xklavier_private_xkb.h"
-/**
+/*
* XKB event handler
*/
-int _XklXkbEventHandler( XEvent *xev )
+gint
+xkl_xkb_process_x_event(XklEngine * engine, XEvent * xev)
{
#ifdef XKB_HEADERS_PRESENT
- int i;
- unsigned bit;
- unsigned inds;
- XkbEvent *kev = (XkbEvent*)xev;
-
- if( xev->type != _xklXkbEventType )
- return 0;
-
- if( !( _xklListenerType &
- ( XKLL_MANAGE_WINDOW_STATES | XKLL_TRACK_KEYBOARD_STATE ) ) )
- return 0;
-
- XklDebug( 150, "Xkb event detected\n" );
-
- switch ( kev->any.xkb_type )
- {
- /**
- * Group is changed!
- */
- case XkbStateNotify:
+ gint i;
+ guint bit;
+ guint inds;
+ XkbEvent *kev = (XkbEvent *) xev;
+
+ if (xev->type != xkl_engine_backend(engine, XklXkb, event_type))
+ return 0;
+
+ if (!(xkl_engine_priv(engine, listener_type) &
+ (XKLL_MANAGE_WINDOW_STATES | XKLL_TRACK_KEYBOARD_STATE)))
+ return 0;
+
+ xkl_debug(150, "Xkb event detected\n");
+
+ switch (kev->any.xkb_type) {
+ /*
+ * Group is changed!
+ */
+ case XkbStateNotify:
#define GROUP_CHANGE_MASK \
( XkbGroupStateMask | XkbGroupBaseMask | XkbGroupLatchMask | XkbGroupLockMask )
- XklDebug( 150,
- "XkbStateNotify detected, changes: %X/(mask %X), new group %d\n",
- kev->state.changed, GROUP_CHANGE_MASK,
- kev->state.locked_group );
-
- if( kev->state.changed & GROUP_CHANGE_MASK )
- _XklStateModificationHandler( GROUP_CHANGED,
- kev->state.locked_group,
- 0,
- False );
- else /* ...not interested... */
- {
- XklDebug( 200,
- "This type of state notification is not regarding groups\n" );
- if ( kev->state.locked_group != _xklCurState.group )
- XklDebug( 0,
- "ATTENTION! Currently cached group %d is not equal to the current group from the event: %d\n!",
- _xklCurState.group,
- kev->state.locked_group );
- }
-
- break;
-
- /**
- * Indicators are changed!
- */
- case XkbIndicatorStateNotify:
-
- XklDebug( 150, "XkbIndicatorStateNotify\n" );
-
- inds = _xklCurState.indicators;
-
- ForPhysIndicators( i, bit ) if( kev->indicators.changed & bit )
- {
- if( kev->indicators.state & bit )
- inds |= bit;
- else
- inds &= ~bit;
- }
-
- _XklStateModificationHandler( INDICATORS_CHANGED,
- 0,
- inds,
- True );
- break;
-
- /**
- * The configuration is changed!
- */
- case XkbIndicatorMapNotify:
- case XkbControlsNotify:
- case XkbNamesNotify:
+ xkl_debug(150,
+ "XkbStateNotify detected, changes: %X/(mask %X), new group %d\n",
+ kev->state.changed, GROUP_CHANGE_MASK,
+ kev->state.locked_group);
+
+ if (kev->state.changed & GROUP_CHANGE_MASK)
+ xkl_engine_process_state_modification(engine,
+ GROUP_CHANGED,
+ kev->state.
+ locked_group,
+ 0, FALSE);
+ else { /* ...not interested... */
+
+ xkl_debug(200,
+ "This type of state notification is not regarding groups\n");
+ if (kev->state.locked_group !=
+ xkl_engine_priv(engine, curr_state).group)
+ xkl_debug(0,
+ "ATTENTION! Currently cached group %d is not equal to the current group from the event: %d\n!",
+ xkl_engine_priv(engine,
+ curr_state).
+ group, kev->state.locked_group);
+ }
+
+ break;
+
+ /*
+ * Indicators are changed!
+ */
+ case XkbIndicatorStateNotify:
+
+ xkl_debug(150, "XkbIndicatorStateNotify\n");
+
+ inds = xkl_engine_priv(engine, curr_state).indicators;
+
+ ForPhysIndicators(i,
+ bit) if (kev->indicators.changed & bit) {
+ if (kev->indicators.state & bit)
+ inds |= bit;
+ else
+ inds &= ~bit;
+ }
+
+ xkl_engine_process_state_modification(engine,
+ INDICATORS_CHANGED,
+ 0, inds, TRUE);
+ break;
+
+ /*
+ * The configuration is changed!
+ */
+ case XkbIndicatorMapNotify:
+ case XkbControlsNotify:
+ case XkbNamesNotify:
#if 0
- /* not really fair - but still better than flooding... */
- XklDebug( 200, "warning: configuration event %s is not actually processed\n",
- _XklXkbGetXkbEventName( kev->any.xkb_type ) );
- break;
+ /* not really fair - but still better than flooding... */
+ XklDebug(200,
+ "warning: configuration event %s is not actually processed\n",
+ _XklXkbGetXkbEventName(kev->any.xkb_type));
+ break;
#endif
- case XkbNewKeyboardNotify:
- XklDebug( 150, "%s\n",
- _XklXkbGetXkbEventName( kev->any.xkb_type ) );
- _XklResetAllInfo( "XKB event: XkbNewKeyboardNotify" );
- break;
-
- /**
- * ...Not interested...
- */
- default:
- XklDebug( 150, "Unknown XKB event %d [%s]\n",
- kev->any.xkb_type, _XklXkbGetXkbEventName( kev->any.xkb_type ) );
- return 0;
- }
- return 1;
+ case XkbNewKeyboardNotify:
+ xkl_debug(150, "%s\n",
+ xkl_xkb_event_get_name(kev->any.xkb_type));
+ xkl_engine_reset_all_info(engine,
+ "XKB event: XkbNewKeyboardNotify");
+ break;
+
+ /*
+ * ...Not interested...
+ */
+ default:
+ xkl_debug(150, "Unknown XKB event %d [%s]\n",
+ kev->any.xkb_type,
+ xkl_xkb_event_get_name(kev->any.xkb_type));
+ return 0;
+ }
+ return 1;
#else
- return 0;
+ return 0;
#endif
}
-void _XklXkbSetIndicators( const XklState *windowState )
+void
+xkl_xkb_set_indicators(XklEngine * engine, const XklState * window_state)
{
#ifdef XKB_HEADERS_PRESENT
- int i;
- unsigned bit;
-
- ForPhysIndicators( i,
- bit ) if( _xklXkb->names->indicators[i] != None )
- {
- Bool status;
- status = _XklSetIndicator( i,
- ( windowState->indicators & bit ) != 0 );
- XklDebug( 150, "Set indicator \"%s\"/%d to %d: %d\n",
- _xklIndicatorNames[i],
- _xklXkb->names->indicators[i],
- windowState->indicators & bit,
- status );
- }
+ int i;
+ unsigned bit;
+
+ XkbDescPtr cached =
+ xkl_engine_backend(engine, XklXkb, cached_desc);
+ ForPhysIndicators(i, bit) if (cached->names->indicators[i] != None) {
+ gboolean status;
+ status = xkl_xkb_set_indicator(engine, i,
+ (window_state->
+ indicators & bit) != 0);
+ xkl_debug(150, "Set indicator \"%s\"/%d to %d: %d\n",
+ xkl_engine_backend(engine, XklXkb,
+ indicator_names)[i],
+ cached->names->indicators[i],
+ window_state->indicators & bit, status);
+ }
#endif
}
diff --git a/libxklavier/xklavier_evt_xmm.c b/libxklavier/xklavier_evt_xmm.c
index 7574f3e..91d3699 100644
--- a/libxklavier/xklavier_evt_xmm.c
+++ b/libxklavier/xklavier_evt_xmm.c
@@ -3,170 +3,190 @@
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <X11/Xlibint.h>
#include <X11/keysym.h>
#include "xklavier_private.h"
#include "xklavier_private_xmm.h"
-static int _XklXmmKeypressEventHandler( XKeyPressedEvent* kpe )
+static gint
+xkl_xmm_process_keypress_event(XklEngine * engine, XKeyPressedEvent * kpe)
{
- if( _xklListenerType & XKLL_MANAGE_LAYOUTS )
- {
- XklDebug( 200, "Processing the KeyPress event\n" );
- int currentShortcut = 0;
- const XmmSwitchOptionPtr sop = _XklXmmFindSwitchOption( kpe->keycode,
- kpe->state,
- &currentShortcut );
- if( sop != NULL )
- {
- XklDebug( 150, "It is THE shortcut\n" );
- XklState state;
- _XklXmmGetRealState( &state );
- if( state.group != -1 )
- {
- int newGroup = ( state.group + sop->shortcutSteps[currentShortcut] ) %
- currentXmmConfig.numLayouts;
- XklDebug( 150, "Setting new xmm group %d\n", newGroup );
- _XklXmmLockGroup( newGroup );
- return 1;
- }
- }
- }
- return 0;
+ if (xkl_engine_priv(engine, listener_type) & XKLL_MANAGE_LAYOUTS) {
+ xkl_debug(200, "Processing the KeyPress event\n");
+ gint current_shortcut = 0;
+ const XmmSwitchOption *sop =
+ xkl_xmm_find_switch_option(engine, kpe->keycode,
+ kpe->state,
+ &current_shortcut);
+ if (sop != NULL) {
+ xkl_debug(150, "It is THE shortcut\n");
+ XklState state;
+ xkl_xmm_get_server_state(engine, &state);
+ if (state.group != -1) {
+ gint new_group =
+ (state.group +
+ sop->
+ shortcut_steps[current_shortcut]) %
+ g_strv_length(xkl_engine_backend
+ (engine, XklXmm,
+ current_config).
+ layouts);
+ xkl_debug(150,
+ "Setting new xmm group %d\n",
+ new_group);
+ xkl_xmm_lock_group(engine, new_group);
+ return 1;
+ }
+ }
+ }
+ return 0;
}
-static int _XklXmmPropertyEventHandler( XPropertyEvent* kpe )
+static gint
+xkl_xmm_process_property_event(XklEngine * engine, XPropertyEvent * kpe)
{
- XklDebug( 200, "Processing the PropertyNotify event: %d/%d\n",
- kpe->atom, xmmStateAtom );
- /**
+ Atom state_atom = xkl_engine_backend(engine, XklXmm, state_atom);
+ xkl_debug(200, "Processing the PropertyNotify event: %d/%d\n",
+ kpe->atom, state_atom);
+ /*
* Group is changed!
*/
- if( kpe->atom == xmmStateAtom )
- {
- XklState state;
- _XklXmmGetRealState( &state );
-
- if( _xklListenerType & XKLL_MANAGE_LAYOUTS )
- {
- XklDebug( 150, "Current group from the root window property %d\n", state.group );
- _XklXmmUngrabShortcuts();
- _XklXmmActualizeGroup( state.group );
- _XklXmmGrabShortcuts();
- return 1;
- }
-
- if( _xklListenerType &
- ( XKLL_MANAGE_WINDOW_STATES | XKLL_TRACK_KEYBOARD_STATE ) )
- {
- XklDebug( 150,
- "XMM state changed, new 'group' %d\n",
- state.group );
-
- _XklStateModificationHandler( GROUP_CHANGED,
- state.group,
- 0,
- False );
- }
- } else
- /**
+ if (kpe->atom == state_atom) {
+ XklState state;
+ xkl_xmm_get_server_state(engine, &state);
+
+ if (xkl_engine_priv(engine, listener_type) &
+ XKLL_MANAGE_LAYOUTS) {
+ xkl_debug(150,
+ "Current group from the root window property %d\n",
+ state.group);
+ xkl_xmm_shortcuts_ungrab(engine);
+ xkl_xmm_actualize_group(engine, state.group);
+ xkl_xmm_shortcuts_grab(engine);
+ return 1;
+ }
+
+ if (xkl_engine_priv(engine, listener_type) &
+ (XKLL_MANAGE_WINDOW_STATES |
+ XKLL_TRACK_KEYBOARD_STATE)) {
+ xkl_debug(150,
+ "XMM state changed, new 'group' %d\n",
+ state.group);
+
+ xkl_engine_process_state_modification(engine,
+ GROUP_CHANGED,
+ state.group,
+ 0, False);
+ }
+ } else
+ /*
* Configuration is changed!
*/
- if( kpe->atom == xklVTable->baseConfigAtom )
- {
- _XklResetAllInfo( "base config atom changed" );
- }
-
- return 0;
+ if (kpe->atom == xkl_engine_priv(engine, base_config_atom)) {
+ xkl_engine_reset_all_info(engine,
+ "base config atom changed");
+ }
+
+ return 0;
}
-/**
+/*
* XMM event handler
*/
-int _XklXmmEventHandler( XEvent *xev )
+gint
+xkl_xmm_process_x_event(XklEngine * engine, XEvent * xev)
{
- switch( xev->type )
- {
- case KeyPress:
- return _XklXmmKeypressEventHandler( (XKeyPressedEvent*)xev );
- case PropertyNotify:
- return _XklXmmPropertyEventHandler( (XPropertyEvent*)xev );
- }
- return 0;
+ switch (xev->type) {
+ case KeyPress:
+ return xkl_xmm_process_keypress_event(engine,
+ (XKeyPressedEvent *)
+ xev);
+ case PropertyNotify:
+ return xkl_xmm_process_property_event(engine,
+ (XPropertyEvent *)
+ xev);
+ }
+ return 0;
}
-/**
+/*
* We have to find which of Shift/Lock/Control/ModX masks
* belong to Caps/Num/Scroll lock
*/
-static void _XklXmmInitXmmIndicatorsMap( int* pCapsLockMask,
- int* pNumLockMask,
- int* pScrollLockMask )
+static void
+xkl_xmm_init_xmm_indicators_map(XklEngine * engine,
+ guint * p_caps_lock_mask,
+ guint * p_num_lock_mask,
+ guint * p_scroll_lock_mask)
{
- XModifierKeymap *xmkm = NULL;
- KeyCode *kcmap, nlkc, clkc, slkc;
- int m, k, mask;
-
- xmkm = XGetModifierMapping( _xklDpy );
- if( xmkm )
- {
- clkc = XKeysymToKeycode( _xklDpy, XK_Num_Lock );
- nlkc = XKeysymToKeycode( _xklDpy, XK_Caps_Lock );
- slkc = XKeysymToKeycode( _xklDpy, XK_Scroll_Lock );
-
- kcmap = xmkm->modifiermap;
- mask = 1;
- for( m = 8; --m >= 0; mask <<= 1 )
- for( k = xmkm->max_keypermod; --k >= 0; kcmap++ )
- {
- if( *kcmap == clkc )
- *pCapsLockMask = mask;
- if( *kcmap == slkc )
- *pScrollLockMask = mask;
- if( *kcmap == nlkc )
- *pNumLockMask = mask;
- }
- XFreeModifiermap( xmkm );
- }
+ XModifierKeymap *xmkm = NULL;
+ KeyCode *kcmap, nlkc, clkc, slkc;
+ int m, k, mask;
+
+ Display *display = xkl_engine_get_display(engine);
+ xmkm = XGetModifierMapping(display);
+ if (xmkm) {
+ clkc = XKeysymToKeycode(display, XK_Num_Lock);
+ nlkc = XKeysymToKeycode(display, XK_Caps_Lock);
+ slkc = XKeysymToKeycode(display, XK_Scroll_Lock);
+
+ kcmap = xmkm->modifiermap;
+ mask = 1;
+ for (m = 8; --m >= 0; mask <<= 1)
+ for (k = xmkm->max_keypermod; --k >= 0; kcmap++) {
+ if (*kcmap == clkc)
+ *p_caps_lock_mask = mask;
+ if (*kcmap == slkc)
+ *p_scroll_lock_mask = mask;
+ if (*kcmap == nlkc)
+ *p_num_lock_mask = mask;
+ }
+ XFreeModifiermap(xmkm);
+ }
}
-void _XklXmmGrabIgnoringIndicators( int keycode, int modifiers )
+void
+xkl_xmm_grab_ignoring_indicators(XklEngine * engine, gint keycode,
+ guint modifiers)
{
- int CapsLockMask = 0, NumLockMask = 0, ScrollLockMask = 0;
-
- _XklXmmInitXmmIndicatorsMap( &CapsLockMask, &NumLockMask, &ScrollLockMask );
+ guint caps_lock_mask = 0, num_lock_mask = 0, scroll_lock_mask = 0;
+
+ xkl_xmm_init_xmm_indicators_map(engine, &caps_lock_mask,
+ &num_lock_mask, &scroll_lock_mask);
#define GRAB(mods) \
- XklGrabKey( keycode, modifiers|(mods) )
-
- GRAB( 0 );
- GRAB( CapsLockMask );
- GRAB( NumLockMask );
- GRAB( ScrollLockMask );
- GRAB( CapsLockMask | NumLockMask );
- GRAB( CapsLockMask | ScrollLockMask );
- GRAB( NumLockMask | ScrollLockMask );
- GRAB( CapsLockMask | NumLockMask | ScrollLockMask );
+ xkl_engine_grab_key(engine, keycode, modifiers|(mods))
+
+ GRAB(0);
+ GRAB(caps_lock_mask);
+ GRAB(num_lock_mask);
+ GRAB(scroll_lock_mask);
+ GRAB(caps_lock_mask | num_lock_mask);
+ GRAB(caps_lock_mask | scroll_lock_mask);
+ GRAB(num_lock_mask | scroll_lock_mask);
+ GRAB(caps_lock_mask | num_lock_mask | scroll_lock_mask);
#undef GRAB
}
-void _XklXmmUngrabIgnoringIndicators( int keycode, int modifiers )
+void
+xkl_xmm_ungrab_ignoring_indicators(XklEngine * engine, gint keycode,
+ guint modifiers)
{
- int CapsLockMask = 0, NumLockMask = 0, ScrollLockMask = 0;
+ guint caps_lock_mask = 0, num_lock_mask = 0, scroll_lock_mask = 0;
+
+ xkl_xmm_init_xmm_indicators_map(engine, &caps_lock_mask,
+ &num_lock_mask, &scroll_lock_mask);
- _XklXmmInitXmmIndicatorsMap( &CapsLockMask, &NumLockMask, &ScrollLockMask );
-
#define UNGRAB(mods) \
- XklUngrabKey( keycode, modifiers|(mods) )
-
- UNGRAB( 0 );
- UNGRAB( CapsLockMask );
- UNGRAB( NumLockMask );
- UNGRAB( ScrollLockMask );
- UNGRAB( CapsLockMask | NumLockMask );
- UNGRAB( CapsLockMask | ScrollLockMask );
- UNGRAB( NumLockMask | ScrollLockMask );
- UNGRAB( CapsLockMask | NumLockMask | ScrollLockMask );
+ xkl_engine_ungrab_key(engine, keycode, modifiers|(mods))
+
+ UNGRAB(0);
+ UNGRAB(caps_lock_mask);
+ UNGRAB(num_lock_mask);
+ UNGRAB(scroll_lock_mask);
+ UNGRAB(caps_lock_mask | num_lock_mask);
+ UNGRAB(caps_lock_mask | scroll_lock_mask);
+ UNGRAB(num_lock_mask | scroll_lock_mask);
+ UNGRAB(caps_lock_mask | num_lock_mask | scroll_lock_mask);
#undef UNGRAB
}
diff --git a/libxklavier/xklavier_private.h b/libxklavier/xklavier_private.h
index 0dfecc0..30aef9e 100644
--- a/libxklavier/xklavier_private.h
+++ b/libxklavier/xklavier_private.h
@@ -3,350 +3,384 @@
#include <stdio.h>
-#include <libxklavier/xklavier_config.h>
+#include <libxml/xpath.h>
-typedef Bool ( *XklConfigActivateHandler )( const XklConfigRecPtr data );
+#include <libxklavier/xklavier.h>
-typedef void ( *XklConfigInitHandler )( void );
-
-typedef Bool ( *XklConfigLoadRegistryHandler )( void );
-
-typedef Bool ( *XklConfigWriteFileHandler )( const char *fileName,
- const XklConfigRecPtr data,
- const Bool binary );
-
-typedef int ( *XklEventHandler )( XEvent *xev );
-
-typedef void ( *XklFreeAllInfoHandler )( void );
-
-typedef const char **( *XklGetGroupNamesHandler )( void );
-
-typedef unsigned ( *XklGetMaxNumGroupsHandler )( void );
-
-typedef unsigned ( *XklGetNumGroupsHandler )( void );
-
-typedef void ( *XklGetRealStateHandler)( XklState * curState_return );
-
-typedef Bool ( *XklIfCachedInfoEqualsActualHandler) ( void );
-
-typedef Bool ( *XklLoadAllInfoHandler )( void );
-
-typedef void ( *XklLockGroupHandler )( int group );
-
-typedef int ( *XklPauseResumeListenHandler )( void );
-
-typedef void ( *XklSetIndicatorsHandler )( const XklState *windowState );
-
-typedef struct
-{
- /**
- * Backend name
- */
- const char *id;
-
- /**
- * Functions supported by the backend, combination of XKLF_* constants
- */
- int features;
-
- /**
- * Activates the configuration.
- * xkb: create proper the XkbDescRec and send it to the server
- * xmodmap: save the property, init layout #1
- */
- XklConfigActivateHandler xklConfigActivateHandler;
-
- /**
- * Background-specific initialization.
- * xkb: XkbInitAtoms - init internal xkb atoms table
- * xmodmap: void.
- */
- XklConfigInitHandler xklConfigInitHandler; /* private */
-
- /**
- * Loads the registry tree into DOM (using whatever path(s))
- * The XklConfigFreeRegistry is static - no virtualization necessary.
- * xkb: loads xml from XKB_BASE+"/rules/"+ruleset+".xml"
- * xmodmap: loads xml from XMODMAP_BASE+"/"+ruleset+".xml"
- */
- XklConfigLoadRegistryHandler xklConfigLoadRegistryHandler;
-
- /**
- * Write the configuration into the file (binary/textual)
- * xkb: write xkb or xkm file
- * xmodmap: if text requested, just dump XklConfigRec to the
- * file - not really useful. If binary - fail (not supported)
- */
- XklConfigWriteFileHandler xklConfigWriteFileHandler;
-
- /**
- * Handles X events.
- * xkb: XkbEvent handling
- * xmodmap: keep track on the root window properties. What else can we do?
- */
- XklEventHandler xklEventHandler;
-
- /**
- * Flushes the cached server config info.
- * xkb: frees XkbDesc
- * xmodmap: frees internal XklConfigRec
- */
- XklFreeAllInfoHandler xklFreeAllInfoHandler; /* private */
-
- /**
- * Get the list of the group names
- * xkb: return cached list of the group names
- * xmodmap: return the list of layouts from the internal XklConfigRec
- */
- XklGetGroupNamesHandler xklGetGroupNamesHandler;
-
- /**
- * Get the maximum number of loaded groups
- * xkb: returns 1 or XkbNumKbdGroups
- * xmodmap: return 0
- */
- XklGetMaxNumGroupsHandler xklGetMaxNumGroupsHandler;
-
- /**
- * Get the number of loaded groups
- * xkb: return from the cached XkbDesc
- * xmodmap: return number of layouts from internal XklConfigRec
- */
- XklGetNumGroupsHandler xklGetNumGroupsHandler;
-
- /**
- * Gets the current stateCallback
- * xkb: XkbGetState and XkbGetIndicatorState
- * xmodmap: check the root window property (regarding the group)
- */
- XklGetRealStateHandler xklGetRealStateHandler;
-
- /**
- * Compares the cached info with the actual one, from the server
- * xkb: Compares some parts of XkbDescPtr
- * xmodmap: returns False
- */
- XklIfCachedInfoEqualsActualHandler xklIfCachedInfoEqualsActualHandler;
-
- /**
- * Loads the configuration info from the server
- * xkb: loads XkbDesc, names, indicators
- * xmodmap: loads internal XklConfigRec from server
- */
- XklLoadAllInfoHandler xklLoadAllInfoHandler; /* private */
-
- /**
- * Switches the keyboard to the group N
- * xkb: simple one-liner to call the XKB function
- * xmodmap: changes the root window property
- * (listener invokes xmodmap with appropriate config file).
- */
- XklLockGroupHandler xklLockGroupHandler;
-
- /**
- * Stop tracking the keyboard-related events
- * xkb: XkbSelectEvents(..., 0)
- * xmodmap: Ungrab the switching shortcut.
- */
- XklPauseResumeListenHandler xklPauseListenHandler;
-
- /**
- * Start tracking the keyboard-related events
- * xkb: XkbSelectEvents + XkbSelectEventDetails
- * xmodmap: Grab the switching shortcut.
- */
- XklPauseResumeListenHandler xklResumeListenHandler;
-
- /**
- * Set the indicators state from the XklState
- * xkb: _XklSetIndicator for all indicators
- * xmodmap: NULL. Not supported
- */
- XklSetIndicatorsHandler xklSetIndicatorsHandler; /* private */
-
- /* all data is private - no direct access */
- /**
- * The base configuration atom.
- * xkb: _XKB_RF_NAMES_PROP_ATOM
- * xmodmap: "_XMM_NAMES"
- */
- Atom baseConfigAtom;
-
- /**
- * The configuration backup atom
- * xkb: "_XKB_RULES_NAMES_BACKUP"
- * xmodmap: "_XMM_NAMES_BACKUP"
- */
- Atom backupConfigAtom;
-
- /**
- * Fallback for missing model
- */
- const char* defaultModel;
-
- /**
- * Fallback for missing layout
- */
- const char* defaultLayout;
-
-} XklVTable;
-
-extern void _XklEnsureVTableInited( void );
-
-extern void _XklAddAppWindow( Window win, Window parent, Bool force,
- XklState * initState );
-extern Bool _XklGetAppWindowBottomToTop( Window win, Window * appWin_return );
-extern Bool _XklGetAppWindow( Window win, Window * appWin_return );
-
-extern void _XklFocusInEvHandler( XFocusChangeEvent * fev );
-extern void _XklFocusOutEvHandler( XFocusChangeEvent * fev );
-extern void _XklPropertyEvHandler( XPropertyEvent * rev );
-extern void _XklCreateEvHandler( XCreateWindowEvent * cev );
-
-extern void _XklErrHandler( Display * dpy, XErrorEvent * evt );
-
-extern Window _XklGetRegisteredParent( Window win );
-extern Bool _XklLoadAllInfo( void );
-extern void _XklFreeAllInfo( void );
-extern void _XklResetAllInfo( const char reason[] );
-extern Bool _XklLoadWindowTree( void );
-extern Bool _XklLoadSubtree( Window window, int level, XklState * initState );
-
-extern Bool _XklHasWmState( Window win );
-
-extern Bool _XklGetAppState( Window appWin, XklState * state_return );
-extern void _XklDelAppState( Window appWin );
-extern void _XklSaveAppState( Window appWin, XklState * state );
-
-extern void _XklSelectInputMerging( Window win, long mask );
-
-extern char *_XklGetDebugWindowTitle( Window win );
-
-extern Status _XklStatusQueryTree( Display * display,
- Window w,
- Window * root_return,
- Window * parent_return,
- Window ** children_return,
- unsigned int *nchildren_return );
-
-extern Bool _XklSetIndicator( int indicatorNum, Bool set );
-
-extern void _XklTryCallStateCallback( XklStateChange changeType,
- XklState * oldState );
-
-extern void _XklI18NInit( );
+enum { WM_NAME,
+ WM_STATE,
+ XKLAVIER_STATE,
+ XKLAVIER_TRANSPARENT,
+ XKLAVIER_ALLOW_SECONDARY,
+ TOTAL_ATOMS
+};
+
+struct _XklEnginePrivate {
+
+ gboolean group_per_toplevel_window;
+
+ gboolean handle_indicators;
+
+ gboolean skip_one_restore;
+
+ gint default_group;
+
+ guint listener_type;
+
+ guint secondary_groups_mask;
+
+ Window root_window;
+
+ Window prev_toplvl_win;
+
+ Window curr_toplvl_win;
+
+ XErrorHandler default_error_handler;
+
+ Status last_error_code;
+
+ XklState curr_state;
+
+ Atom atoms[TOTAL_ATOMS];
+
+ Display *display;
+
+ /*
+ * Backend name
+ */
+ const gchar *backend_id;
+
+ /*
+ * Functions supported by the backend, combination of XKLF_* constants
+ */
+ guint8 features;
+
+ /*
+ * Activates the configuration.
+ * xkb: create proper the XkbDescRec and send it to the server
+ * xmodmap: save the property, init layout #1
+ */
+ gboolean(*activate_config_rec) (XklEngine * engine,
+ const XklConfigRec * data);
+
+ /*
+ * Background-specific initialization.
+ * xkb: XkbInitAtoms - init internal xkb atoms table
+ * xmodmap: void.
+ */
+ void (*init_config_registry) (XklConfigRegistry * config);
+
+ /*
+ * Loads the registry tree into DOM (using whatever path(s))
+ * The XklVTConfigFreeRegistry is static - no virtualization necessary.
+ * xkb: loads xml from XKB_BASE+"/rules/"+ruleset+".xml"
+ * xmodmap: loads xml from XMODMAP_BASE+"/"+ruleset+".xml"
+ */
+ gboolean(*load_config_registry) (XklConfigRegistry * config);
+
+ /*
+ * Write the configuration into the file (binary/textual)
+ * xkb: write xkb or xkm file
+ * xmodmap: if text requested, just dump XklConfigRec to the
+ * file - not really useful. If binary - fail (not supported)
+ */
+ gboolean(*write_config_rec_to_file) (XklEngine * engine,
+ const gchar * file_name,
+ const XklConfigRec * data,
+ const gboolean binary);
+
+ /*
+ * Get the list of the group names
+ * xkb: return cached list of the group names
+ * xmodmap: return the list of layouts from the internal XklConfigRec
+ */
+ const gchar **(*get_groups_names) (XklEngine * engine);
+
+ /*
+ * Get the maximum number of loaded groups
+ * xkb: returns 1 or XkbNumKbdGroups
+ * xmodmap: return 0
+ */
+ guint(*get_max_num_groups) (XklEngine * engine);
+
+ /*
+ * Get the number of loaded groups
+ * xkb: return from the cached XkbDesc
+ * xmodmap: return number of layouts from internal XklConfigRec
+ */
+ guint(*get_num_groups) (XklEngine * engine);
+
+ /*
+ * Switches the keyboard to the group N
+ * xkb: simple one-liner to call the XKB function
+ * xmodmap: changes the root window property
+ * (listener invokes xmodmap with appropriate config file).
+ */
+ void (*lock_group) (XklEngine * engine, gint group);
+
+ /*
+ * Handles X events.
+ * xkb: XkbEvent handling
+ * xmodmap: keep track on the root window properties. What else can we do?
+ */
+ gint(*process_x_event) (XklEngine * engine, XEvent * xev);
+
+ /*
+ * Flushes the cached server config info.
+ * xkb: frees XkbDesc
+ * xmodmap: frees internal XklConfigRec
+ */
+ void (*free_all_info) (XklEngine * engine);
+
+ /*
+ * Compares the cached info with the actual one, from the server
+ * xkb: Compares some parts of XkbDescPtr
+ * xmodmap: returns False
+ */
+ gboolean(*if_cached_info_equals_actual) (XklEngine * engine);
+
+ /*
+ * Loads the configuration info from the server
+ * xkb: loads XkbDesc, names, indicators
+ * xmodmap: loads internal XklConfigRec from server
+ */
+ gboolean(*load_all_info) (XklEngine * engine);
+
+ /*
+ * Gets the current state
+ * xkb: XkbGetState and XkbGetIndicatorState
+ * xmodmap: check the root window property (regarding the group)
+ */
+ void (*get_server_state) (XklEngine * engine,
+ XklState * current_state_out);
+
+ /*
+ * Stop tracking the keyboard-related events
+ * xkb: XkbSelectEvents(..., 0)
+ * xmodmap: Ungrab the switching shortcut.
+ */
+ gint(*pause_listen) (XklEngine * engine);
+
+ /*
+ * Start tracking the keyboard-related events
+ * xkb: XkbSelectEvents + XkbSelectEventDetails
+ * xmodmap: Grab the switching shortcut.
+ */
+ gint(*resume_listen) (XklEngine * engine);
+
+ /*
+ * Set the indicators state from the XklState
+ * xkb: XklSetIndicator for all indicators
+ * xmodmap: NULL. Not supported
+ */
+ void (*set_indicators) (XklEngine * engine,
+ const XklState * window_state);
+
+ /*
+ * Perform the cleanup
+ */
+ void (*finalize) (XklEngine * engine);
+
+ /* all data is private - no direct access */
+ /*
+ * The base configuration atom.
+ * xkb: _XKB_RF_NAMES_PROP_ATOM
+ * xmodmap: "_XMM_NAMES"
+ */
+ Atom base_config_atom;
+
+ /*
+ * The configuration backup atom
+ * xkb: "_XKB_RULES_NAMES_BACKUP"
+ * xmodmap: "_XMM_NAMES_BACKUP"
+ */
+ Atom backup_config_atom;
+
+ /*
+ * Fallback for missing model
+ */
+ const gchar *default_model;
+
+ /*
+ * Fallback for missing layout
+ */
+ const gchar *default_layout;
+
+ /*
+ * Any stuff backend might need to put in here
+ */
+ gpointer backend;
+};
+
+extern XklEngine *xkl_get_the_engine(void);
+
+struct _XklConfigRegistryPrivate {
+ XklEngine *engine;
+
+ xmlDocPtr doc;
+
+ xmlXPathContextPtr xpath_context;
+};
+
+extern void xkl_engine_ensure_vtable_inited(XklEngine * engine);
+
+extern void xkl_engine_process_focus_in_evt(XklEngine * engine,
+ XFocusChangeEvent * fev);
+extern void xkl_engine_process_focus_out_evt(XklEngine * engine,
+ XFocusChangeEvent * fev);
+extern void xkl_engine_process_property_evt(XklEngine * engine,
+ XPropertyEvent * rev);
+extern void xkl_engine_process_create_window_evt(XklEngine * engine,
+ XCreateWindowEvent * cev);
+
+extern void xkl_process_error(Display * dpy, XErrorEvent * evt);
+
+extern void xkl_engine_process_state_modification(XklEngine * engine,
+ XklEngineStateChange
+ change_type, gint group,
+ unsigned inds,
+ gboolean set_indicators);
+
+extern Window xkl_engine_get_registered_parent(XklEngine * engine,
+ Window win);
+extern void xkl_engine_reset_all_info(XklEngine * engine,
+ const gchar reason[]);
+extern gboolean xkl_engine_load_window_tree(XklEngine * engine);
+extern gboolean xkl_engine_load_subtree(XklEngine * engine, Window window,
+ gint level, XklState * init_state);
+
+extern gboolean xkl_engine_if_window_has_wm_state(XklEngine * engine,
+ Window win);
+
+
+/**
+ * Toplevel window stuff
+ */
+extern void xkl_engine_add_toplevel_window(XklEngine * engine, Window win,
+ Window parent, gboolean force,
+ XklState * init_state);
+
+extern gboolean xkl_engine_find_toplevel_window_bottom_to_top(XklEngine *
+ engine,
+ Window win,
+ Window *
+ toplevel_win_out);
-extern char *_XklLocaleFromUtf8( const char *utf8string );
+extern gboolean xkl_engine_find_toplevel_window(XklEngine * engine,
+ Window win,
+ Window * toplevel_win_out);
-extern int _XklGetLanguagePriority( const char *language );
+extern gboolean xkl_engine_is_toplevel_window_transparent(XklEngine *
+ engine,
+ Window
+ toplevel_win);
-extern char* _XklGetRulesSetName( const char defaultRuleset[] );
+extern void xkl_engine_set_toplevel_window_transparent(XklEngine * engine,
+ Window toplevel_win,
+ gboolean
+ transparent);
-extern Bool _XklConfigGetFullFromServer( char **rulesFileOut,
- XklConfigRecPtr data );
+extern gboolean xkl_engine_get_toplevel_window_state(XklEngine * engine,
+ Window toplevel_win,
+ XklState * state_out);
-extern char *_XklConfigRecMergeByComma( const char **array,
- const int arrayLength );
+extern void xkl_engine_remove_toplevel_window_state(XklEngine * engine,
+ Window toplevel_win);
+extern void xkl_engine_save_toplevel_window_state(XklEngine * engine,
+ Window toplevel_win,
+ XklState * state);
+/***/
-extern char *_XklConfigRecMergeLayouts( const XklConfigRecPtr data );
+extern void xkl_engine_select_input_merging(XklEngine * engine, Window win,
+ gulong mask);
-extern char *_XklConfigRecMergeVariants( const XklConfigRecPtr data );
+extern gchar *xkl_get_debug_window_title(XklEngine * engine, Window win);
-extern char *_XklConfigRecMergeOptions( const XklConfigRecPtr data );
+extern Status xkl_engine_query_tree(XklEngine * engine,
+ Window w,
+ Window * root_out,
+ Window * parent_out,
+ Window ** children_out,
+ guint * nchildren_out);
-extern void _XklConfigRecSplitByComma( char ***array,
- int *arraySize, const char *merged );
+extern void xkl_engine_try_call_state_func(XklEngine * engine,
+ XklEngineStateChange
+ change_type,
+ XklState * old_state);
-extern void _XklConfigRecSplitLayouts( XklConfigRecPtr data,
- const char *merged );
+extern void xkl_i18n_init(void);
-extern void _XklConfigRecSplitVariants( XklConfigRecPtr data,
- const char *merged );
+extern gchar *xkl_locale_from_utf8(const gchar * utf8string);
-extern void _XklConfigRecSplitOptions( XklConfigRecPtr data,
- const char *merged );
+extern gint xkl_get_language_priority(const gchar * language);
-extern void XklConfigDump( FILE* file,
- XklConfigRecPtr data );
-
-extern const char *_XklGetEventName( int requestId );
+extern gchar *xkl_engine_get_ruleset_name(XklEngine * engine,
+ const gchar default_ruleset[]);
-extern Bool _XklIsTransparentAppWindow( Window appWin );
+extern gboolean xkl_config_rec_get_full_from_server(gchar **
+ rules_file_out,
+ XklConfigRec * data,
+ XklEngine * engine);
-extern void _XklUpdateCurState( int group, unsigned indicators, const char reason[] );
+extern gchar *xkl_strings_concat_comma_separated(gchar ** array);
-extern void _XklStateModificationHandler( XklStateChange changeType,
- int grp,
- unsigned inds,
- Bool setInds );
+extern void xkl_strings_split_comma_separated(gchar *** array,
+ const gchar * merged);
-extern int _XklXkbInit( void );
+/**
+ * XConfigRec
+ */
+extern gchar *xkl_config_rec_merge_layouts(const XklConfigRec * data);
-extern int _XklXmmInit( void );
+extern gchar *xkl_config_rec_merge_variants(const XklConfigRec * data);
-extern Bool _XklIsOneSwitchToSecondaryGroupAllowed( void );
+extern gchar *xkl_config_rec_merge_options(const XklConfigRec * data);
-extern void _XklOneSwitchToSecondaryGroupPerformed( void );
+extern void xkl_config_rec_split_layouts(XklConfigRec * data,
+ const gchar * merged);
-extern Display *_xklDpy;
+extern void xkl_config_rec_split_variants(XklConfigRec * data,
+ const gchar * merged);
-extern Window _xklRootWindow;
+extern void xkl_config_rec_split_options(XklConfigRec * data,
+ const gchar * merged);
+/***/
-extern XklState _xklCurState;
+extern void xkl_config_rec_dump(FILE * file, XklConfigRec * data);
-extern Window _xklCurClient;
+extern const gchar *xkl_event_get_name(gint type);
-extern Status _xklLastErrorCode;
+extern void xkl_engine_update_current_state(XklEngine * engine, gint group,
+ unsigned indicators,
+ const gchar reason[]);
-extern const char *_xklLastErrorMsg;
+extern gint xkl_xkb_init(XklEngine * engine);
-extern XErrorHandler _xklDefaultErrHandler;
+extern gint xkl_xmm_init(XklEngine * engine);
-extern char *_xklIndicatorNames[];
+extern gboolean
+xkl_engine_is_one_switch_to_secondary_group_allowed(XklEngine * engine);
-enum { WM_NAME,
- WM_STATE,
- XKLAVIER_STATE,
- XKLAVIER_TRANSPARENT,
- XKLAVIER_ALLOW_SECONDARY,
- TOTAL_ATOMS };
+extern void xkl_engine_one_switch_to_secondary_group_performed(XklEngine *
+ engine);
#define XKLAVIER_STATE_PROP_LENGTH 2
/* taken from XFree86 maprules.c */
-#define _XKB_RF_NAMES_PROP_MAXLEN 1024
-
-extern Atom _xklAtoms[];
-
-extern Bool _xklAllowSecondaryGroupOnce;
-
-extern int _xklDefaultGroup;
-
-extern Bool _xklSkipOneRestore;
-
-extern int _xklSecondaryGroupsMask;
-
-extern int _xklDebugLevel;
-
-extern int _xklListenerType;
-
-extern Window _xklPrevAppWindow;
+#define XKB_RF_NAMES_PROP_MAXLEN 1024
#define WINID_FORMAT "%lx"
-extern XklConfigCallback _xklConfigCallback;
+#define xkl_engine_priv(engine,member) (engine)->priv->member
+#define xkl_engine_backend(engine,type,member) ((type*)((engine)->priv->backend))->member
+#define xkl_engine_get_display(engine) (xkl_engine_priv(engine,display))
+#define xkl_engine_vcall(engine,func) (*(engine)->priv->func)
-extern void *_xklConfigCallbackData;
+#define xkl_config_registry_priv(config,member) (config)->priv->member
+#define xkl_config_registry_get_engine(config) ((config)->priv->engine)
-extern XklVTable *xklVTable;
+extern gint xkl_debug_level;
-#ifdef __STRICT_ANSI__
-/* these are functions which are NOT in ANSI C.
- Probably we should provide the implementation */
-extern int snprintf( char *s, size_t maxlen,
- const char *format, ... );
-
-extern char *strdup( const char *s );
-#endif
+extern const gchar *xkl_last_error_message;
#endif
diff --git a/libxklavier/xklavier_private_xkb.h b/libxklavier/xklavier_private_xkb.h
index ce71002..0fa7d15 100644
--- a/libxklavier/xklavier_private_xkb.h
+++ b/libxklavier/xklavier_private_xkb.h
@@ -8,74 +8,99 @@
#define ForPhysIndicators( i, bit ) \
for ( i=0, bit=1; i<XkbNumIndicators; i++, bit<<=1 ) \
- if ( _xklXkb->indicators->phys_indicators & bit )
+ if ( xkl_engine_backend(engine,XklXkb,cached_desc)->indicators->phys_indicators & bit )
-extern int _xklXkbEventType, _xklXkbError;
+typedef struct _XklXkb {
-extern XkbRF_VarDefsRec _xklVarDefs;
+ gint event_type;
-extern XkbDescPtr _xklXkb;
+ gint error_code;
-extern void XklDumpXkbDesc( const char *filename, XkbDescPtr kbd );
+ XkbDescPtr cached_desc;
-extern Bool _XklXkbConfigMultipleLayoutsSupported( void );
+ gchar *indicator_names[XkbNumIndicators];
-extern const char *_XklXkbGetXkbEventName( int xkb_type );
+ XkbDescPtr actual_desc;
-extern Bool _XklXkbConfigPrepareNative( const XklConfigRecPtr data, XkbComponentNamesPtr componentNamesPtr );
+ gchar *group_names[XkbNumKbdGroups];
-extern void _XklXkbConfigCleanupNative( XkbComponentNamesPtr componentNamesPtr );
+} XklXkb;
+
+extern void xkl_engine_dump_xkb_desc(XklEngine * engine,
+ const char *file_name,
+ XkbDescPtr kbd);
+
+extern gboolean xkl_xkb_multiple_layouts_supported(XklEngine * engine);
+
+extern const gchar *xkl_xkb_event_get_name(gint xkb_type);
+
+extern gboolean xkl_xkb_config_native_prepare(XklEngine * engine,
+ const XklConfigRec * data,
+ XkbComponentNamesPtr
+ component_names);
+
+extern void xkl_xkb_config_native_cleanup(XklEngine * engine,
+ XkbComponentNamesPtr
+ component_names);
+
+extern gboolean xkl_xkb_set_indicator(XklEngine * engine,
+ gint indicator_num, gboolean set);
/* Start VTable methods */
-extern Bool _XklXkbConfigActivate( const XklConfigRecPtr data );
+extern gboolean xkl_xkb_activate_config_rec(XklEngine * engine,
+ const XklConfigRec * data);
-extern void _XklXkbConfigInit( void );
+extern void xkl_xkb_init_config_registry(XklConfigRegistry * config);
-extern Bool _XklXkbConfigLoadRegistry( void );
+extern gboolean xkl_xkb_load_config_registry(XklConfigRegistry * config);
-extern Bool _XklXkbConfigWriteFile( const char *fileName,
- const XklConfigRecPtr data,
- const Bool binary );
+extern gboolean xkl_xkb_write_config_rec_to_file(XklEngine * engine,
+ const char *file_name,
+ const XklConfigRec * data,
+ const gboolean binary);
-extern int _XklXkbEventHandler( XEvent * kev );
+extern gint xkl_xkb_process_x_event(XklEngine * engine, XEvent * kev);
-extern void _XklXkbFreeAllInfo( void );
+extern void xkl_xkb_free_all_info(XklEngine * engine);
-extern const char **_XklXkbGetGroupNames( void );
+extern const gchar **xkl_xkb_get_groups_names(XklEngine * engine);
-extern unsigned _XklXkbGetMaxNumGroups( void );
+extern guint xkl_xkb_get_max_num_groups(XklEngine * engine);
-extern unsigned _XklXkbGetNumGroups( void );
+extern guint xkl_xkb_get_num_groups(XklEngine * engine);
-extern void _XklXkbGetRealState( XklState * curState_return );
+extern void xkl_xkb_get_server_state(XklEngine * engine,
+ XklState * current_state_out);
-extern Bool _XklXkbIfCachedInfoEqualsActual( void );
+extern gboolean xkl_xkb_if_cached_info_equals_actual(XklEngine * engine);
-extern Bool _XklXkbLoadAllInfo( void );
+extern gboolean xkl_xkb_load_all_info(XklEngine * engine);
-extern void _XklXkbLockGroup( int group );
+extern void xkl_xkb_lock_group(XklEngine * engine, gint group);
-extern int _XklXkbPauseListen( void );
+extern gint xkl_xkb_pause_listen(XklEngine * engine);
-extern int _XklXkbResumeListen( void );
+extern gint xkl_xkb_resume_listen(XklEngine * engine);
-extern void _XklXkbSetIndicators( const XklState *windowState );
+extern void xkl_xkb_set_indicators(XklEngine * engine,
+ const XklState * window_state);
+
+extern void xkl_xkb_term(XklEngine * engine);
/* End of VTable methods */
#else
-/**
+/*
* VERY VERY BAD STYLE, some kind of 'protected' methods -
* but some programs may want to hook into them.
*/
-extern Bool _XklXkbConfigPrepareNative( const XklConfigRecPtr data, void * componentNamesPtr );
+extern gboolean xkl_xkb_config_prepare_native(const XklConfigRec * data,
+ gpointer component_names);
-extern void _XklXkbConfigCleanupNative( void * componentNamesPtr );
+extern void xkl_xkb_config_cleanup_native(gpointer component_names);
#endif
-extern Bool _xklXkbExtPresent;
-
#endif
diff --git a/libxklavier/xklavier_private_xmm.h b/libxklavier/xklavier_private_xmm.h
index f83cd07..178e7d2 100644
--- a/libxklavier/xklavier_private_xmm.h
+++ b/libxklavier/xklavier_private_xmm.h
@@ -1,77 +1,92 @@
#ifndef __XKLAVIER_PRIVATE_XMM_H__
#define __XKLAVIER_PRIVATE_XMM_H__
-typedef struct _XmmShortcut
-{
- int keysym;
- int modifiers;
-} XmmShortcut, *XmmShortcutPtr;
+typedef struct _XmmShortcut {
+ guint keysym;
+ guint modifiers;
+} XmmShortcut;
#define MAX_SHORTCUTS_PER_OPTION 4
-typedef struct _XmmSwitchOption
-{
- const char* optionName;
- int numShortcuts;
- XmmShortcut shortcuts[MAX_SHORTCUTS_PER_OPTION];
- int shortcutSteps[MAX_SHORTCUTS_PER_OPTION];
-} XmmSwitchOption, *XmmSwitchOptionPtr;
+typedef struct _XmmSwitchOption {
+ XmmShortcut shortcuts[MAX_SHORTCUTS_PER_OPTION + 1];
+ gint shortcut_steps[MAX_SHORTCUTS_PER_OPTION + 1];
+} XmmSwitchOption;
-extern char* currentXmmRules;
+typedef struct _XklXmm {
+ gchar *current_rules;
-extern XklConfigRec currentXmmConfig;
+ XklConfigRec current_config;
-extern Atom xmmStateAtom;
+ Atom state_atom;
+
+ GHashTable *switch_options;
+} XklXmm;
/* in the ideal world this should be a hashmap */
-extern XmmSwitchOption allSwitchOptions[];
+extern void xkl_xmm_grab_ignoring_indicators(XklEngine * engine,
+ gint keycode,
+ guint modifiers);
-extern void _XklXmmGrabIgnoringIndicators( int keycode, int modifiers );
+extern void xkl_xmm_ungrab_ignoring_indicators(XklEngine * engine,
+ gint keycode,
+ guint modifiers);
-extern void _XklXmmUngrabIgnoringIndicators( int keycode, int modifiers );
+extern void xkl_xmm_shortcuts_grab(XklEngine * engine);
-extern void _XklXmmGrabShortcuts( void );
+extern void xkl_xmm_shortcuts_ungrab(XklEngine * engine);
-extern void _XklXmmUngrabShortcuts( void );
+extern const gchar *xkl_xmm_shortcut_get_current_option_name(XklEngine *
+ engine);
-extern const char* _XklXmmGetCurrentShortcutOptionName( void );
+XmmSwitchOption *xkl_xmm_shortcut_get_current(XklEngine * engine);
-XmmSwitchOptionPtr _XklXmmGetCurrentShortcut( void );
+extern void xkl_xmm_actualize_group(XklEngine * engine, gint group);
-extern void _XklXmmActualizeGroup( int group );
+const XmmSwitchOption *xkl_xmm_find_switch_option(XklEngine * engine,
+ gint keycode,
+ guint state,
+ gint *
+ current_shortcut_out);
-XmmSwitchOptionPtr _XklXmmFindSwitchOption( unsigned keycode,
- unsigned state,
- int * currentShortcut_rv );
+extern void xkl_xmm_init_switch_options(XklXmm * xmm);
+extern void xkl_xmm_term_switch_options(XklXmm * xmm);
/* Start VTable methods */
-extern Bool _XklXmmConfigActivate( const XklConfigRecPtr data );
+extern gboolean xkl_xmm_activate_config_rec(XklEngine * engine,
+ const XklConfigRec * data);
+
+extern void xkl_xmm_init_config_registry(XklConfigRegistry * config);
+
+extern gboolean xkl_xmm_load_config_registry(XklConfigRegistry * config);
-extern void _XklXmmConfigInit( void );
+extern gint xkl_xmm_process_x_event(XklEngine * engine, XEvent * kev);
-extern Bool _XklXmmConfigLoadRegistry( void );
+extern void xkl_xmm_free_all_info(XklEngine * engine);
-extern int _XklXmmEventHandler( XEvent * kev );
+extern const gchar **xkl_xmm_get_groups_names(XklEngine * engine);
-extern void _XklXmmFreeAllInfo( void );
+extern guint xkl_xmm_get_max_num_groups(XklEngine * engine);
-extern const char **_XklXmmGetGroupNames( void );
+extern guint xkl_xmm_get_num_groups(XklEngine * engine);
-extern unsigned _XklXmmGetMaxNumGroups( void );
+extern void xkl_xmm_lock_group(XklEngine * engine, gint group);
-extern unsigned _XklXmmGetNumGroups( void );
+extern void xkl_xmm_get_server_state(XklEngine * engine,
+ XklState * current_state_out);
-extern void _XklXmmGetRealState( XklState * curState_return );
+extern gboolean xkl_xmm_if_cached_info_equals_actual(XklEngine * engine);
-extern Bool _XklXmmIfCachedInfoEqualsActual( void );
+extern gboolean xkl_xmm_load_all_info(XklEngine * engine);
-extern Bool _XklXmmLoadAllInfo( void );
+extern gint xkl_xmm_listen_pause(XklEngine * engine);
-extern void _XklXmmLockGroup( int group );
+extern gint xkl_xmm_listen_resume(XklEngine * engine);
-extern int _XklXmmPauseListen( void );
+extern void xkl_xmm_set_indicators(XklEngine * engine,
+ const XklState * window_state);
-extern int _XklXmmResumeListen( void );
+extern void xkl_xmm_term(XklEngine * engine);
/* End of VTable methods */
diff --git a/libxklavier/xklavier_props.c b/libxklavier/xklavier_props.c
index 52a98fe..b18d142 100644
--- a/libxklavier/xklavier_props.c
+++ b/libxklavier/xklavier_props.c
@@ -1,6 +1,6 @@
#include <errno.h>
-#include <string.h>
#include <locale.h>
+#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
@@ -9,417 +9,465 @@
#include "config.h"
-#include "xklavier.h"
-#include "xklavier_config.h"
#include "xklavier_private.h"
-void XklConfigRecInit( XklConfigRecPtr data )
+static GObjectClass *parent_class = NULL;
+
+static void xkl_config_rec_destroy(XklConfigRec * data);
+
+G_DEFINE_TYPE(XklConfigItem, xkl_config_item, G_TYPE_OBJECT)
+
+static void
+xkl_config_item_init(XklConfigItem * this)
{
- /* clear the structure VarDefsPtr... */
- memset( ( void * ) data, 0, sizeof( XklConfigRec ) );
}
-static Bool PtrsEqual( char* p1, char* p2 )
+static void
+xkl_config_item_class_init(XklConfigItemClass * klass)
{
- if ( p1 == p2 )
- return True;
- if ( ( p1 == NULL && p2 != NULL ) ||
- ( p1 != NULL && p2 == NULL ) )
- return False;
- return !strcmp( p1, p2 );
}
-static Bool ListsEqual( int numItems1, char** items1,
- int numItems2, char** items2 )
+XklConfigItem *
+xkl_config_item_new(void)
{
- int i;
- if ( numItems1 != numItems2 )
- return False;
- if ( items1 == items2 )
- return True;
- for( i = numItems1; --i >= 0; )
- if ( !PtrsEqual( *items1++ , *items2++ ) )
- return False;
- return True;
+ return
+ XKL_CONFIG_ITEM(g_object_new
+ (xkl_config_item_get_type(), NULL));
}
-static Bool _XklGetDefaultNamesProp( char **rulesFileOut, XklConfigRecPtr data )
+G_DEFINE_TYPE(XklConfigRec, xkl_config_rec, G_TYPE_OBJECT)
+
+static void
+xkl_config_rec_finalize(GObject * obj)
{
- if ( rulesFileOut != NULL )
- *rulesFileOut = strdup( XKB_DEFAULT_RULESET );
- data->model = strdup( xklVTable->defaultModel );
-/* keeping Nvariants = Nlayouts */
- data->numLayouts = data->numVariants = 1;
- data->layouts = malloc( sizeof( char * ) );
- data->layouts[0] = strdup( xklVTable->defaultLayout );
- data->variants = malloc( sizeof( char * ) );
- data->variants[0] = strdup( "" );
- data->numOptions = 0;
- data->options = NULL;
- return True;
+ XklConfigRec *this = (XklConfigRec *) obj;
+ xkl_config_rec_destroy(this);
+ G_OBJECT_CLASS(parent_class)->finalize(obj);
}
-Bool _XklConfigGetFullFromServer( char **rulesFileOut, XklConfigRecPtr data )
+static void
+xkl_config_rec_class_init(XklConfigRecClass * klass)
{
- Bool rv =
- XklGetNamesProp( xklVTable->baseConfigAtom, rulesFileOut, data );
+ GObjectClass *object_class;
- if( !rv )
- rv = _XklGetDefaultNamesProp( rulesFileOut, data );
+ object_class = (GObjectClass *) klass;
+ parent_class = g_type_class_peek_parent(object_class);
+ object_class->finalize = xkl_config_rec_finalize;
+}
- return rv;
+XklConfigRec *
+xkl_config_rec_new(void)
+{
+ return
+ XKL_CONFIG_REC(g_object_new(xkl_config_rec_get_type(), NULL));
}
-Bool XklConfigRecEquals( XklConfigRecPtr data1, XklConfigRecPtr data2 )
+static gboolean
+xkl_strings_equal(gchar * p1, gchar * p2)
{
- if ( data1 == data2 )
- return True;
- if ( !PtrsEqual( data1->model, data2->model ) )
- return False;
- if ( !ListsEqual( data1->numLayouts, data1->layouts,
- data2->numLayouts, data2->layouts ) )
- return False;
- if ( !ListsEqual( data1->numVariants, data1->variants,
- data2->numVariants, data2->variants ) )
- return False;
- return ListsEqual( data1->numOptions, data1->options,
- data2->numOptions, data2->options );
+ if (p1 == p2)
+ return TRUE;
+ if ((p1 == NULL && p2 != NULL) || (p1 != NULL && p2 == NULL))
+ return FALSE;
+ return !g_ascii_strcasecmp(p1, p2);
}
-void XklConfigRecDestroy( XklConfigRecPtr data )
+static gboolean
+xkl_lists_equal(gchar ** items1, gchar ** items2)
{
- int i;
- char **p;
-
- if( data->model != NULL )
- free( data->model );
-
- if( ( p = data->layouts ) != NULL )
- {
- for( i = data->numLayouts; --i >= 0; )
- free( *p++ );
- free( data->layouts );
- }
-
- if( ( p = data->variants ) != NULL )
- {
- for( i = data->numVariants; --i >= 0; )
- free( *p++ );
- free( data->variants );
- }
-
- if( ( p = data->options ) != NULL )
- {
- for( i = data->numOptions; --i >= 0; )
- free( *p++ );
- free( data->options );
- }
+ if (items1 == items2)
+ return TRUE;
+
+ if ((items1 == NULL && items2 != NULL) ||
+ (items1 != NULL && items2 == NULL))
+ return FALSE;
+
+ while (*items1 != NULL && *items2 != NULL)
+ if (!xkl_strings_equal(*items1++, *items2++))
+ return FALSE;
+
+ return (*items1 == NULL && *items2 == NULL);
}
-void XklConfigRecReset( XklConfigRecPtr data )
+static gboolean
+xkl_engine_get_default_names_prop(XklEngine * engine,
+ char **rules_file_out,
+ XklConfigRec * data)
{
- XklConfigRecDestroy( data );
- XklConfigRecInit( data );
+ if (rules_file_out != NULL)
+ *rules_file_out = g_strdup(XKB_DEFAULT_RULESET);
+ data->model = g_strdup(xkl_engine_priv(engine, default_model));
+/* keeping Nvariants = Nlayouts */
+ data->layouts = g_new0(char *, 2);
+ data->layouts[0] =
+ g_strdup(xkl_engine_priv(engine, default_layout));
+ data->variants = g_new0(char *, 2);
+ data->variants[0] = g_strdup("");
+ data->options = NULL;
+ return TRUE;
}
-Bool XklConfigGetFromServer( XklConfigRecPtr data )
+gboolean
+xkl_config_rec_get_full_from_server(char **rules_file_out,
+ XklConfigRec * data,
+ XklEngine * engine)
{
- return _XklConfigGetFullFromServer( NULL, data );
+ gboolean rv = xkl_config_rec_get_from_root_window_property(data,
+ xkl_engine_priv
+ (engine,
+ base_config_atom),
+ rules_file_out,
+ engine);
+
+ if (!rv)
+ rv = xkl_engine_get_default_names_prop(engine,
+ rules_file_out,
+ data);
+
+ return rv;
}
-Bool XklConfigGetFromBackup( XklConfigRecPtr data )
+gboolean
+xkl_config_rec_equals(XklConfigRec * data1, XklConfigRec * data2)
{
- Bool rv =
- XklGetNamesProp( xklVTable->backupConfigAtom, NULL, data );
+ if (data1 == data2)
+ return TRUE;
+ if (!xkl_strings_equal(data1->model, data2->model))
+ return FALSE;
+ if (!xkl_lists_equal(data1->layouts, data2->layouts))
+ return FALSE;
+ if (!xkl_lists_equal(data1->variants, data2->variants))
+ return FALSE;
+ return xkl_lists_equal(data1->options, data2->options);
+}
- return rv;
+void
+xkl_config_rec_init(XklConfigRec * data)
+{
+ /* clear the structure VarDefsPtr... */
+ data->model = NULL;
+ data->layouts = data->variants = data->options = NULL;
}
-Bool XklBackupNamesProp( void )
+void
+xkl_config_rec_destroy(XklConfigRec * data)
{
- Bool rv = True;
- char *rf = NULL;
- XklConfigRec data;
- Bool cgp = False;
-
- XklConfigRecInit( &data );
- if( XklGetNamesProp
- ( xklVTable->backupConfigAtom, NULL, &data ) )
- {
- XklConfigRecDestroy( &data );
- return True;
- }
- /* "backup" property is not defined */
- XklConfigRecReset( &data );
- cgp = _XklConfigGetFullFromServer( &rf, &data );
-
- if ( cgp )
- {
-#if 0
- int i;
- XklDebug( 150, "Original model: [%s]\n", data.model );
+ if (data->model != NULL)
+ g_free(data->model);
- XklDebug( 150, "Original layouts(%d):\n", data.numLayouts );
- for( i = data.numLayouts; --i >= 0; )
- XklDebug( 150, "%d: [%s]\n", i, data.layouts[i] );
+ g_strfreev(data->layouts);
+ g_strfreev(data->variants);
+ g_strfreev(data->options);
+ data->layouts = data->variants = data->options = NULL;
+}
- XklDebug( 150, "Original variants(%d):\n", data.numVariants );
- for( i = data.numVariants; --i >= 0; )
- XklDebug( 150, "%d: [%s]\n", i, data.variants[i] );
+void
+xkl_config_rec_reset(XklConfigRec * data)
+{
+ xkl_config_rec_destroy(data);
+ xkl_config_rec_init(data);
+}
- XklDebug( 150, "Original options(%d):\n", data.numOptions );
- for( i = data.numOptions; --i >= 0; )
- XklDebug( 150, "%d: [%s]\n", i, data.options[i] );
-#endif
- if( !XklSetNamesProp( xklVTable->backupConfigAtom, rf, &data ) )
- {
- XklDebug( 150, "Could not backup the configuration" );
- rv = False;
- }
- if( rf != NULL )
- free( rf );
- } else
- {
- XklDebug( 150, "Could not get the configuration for backup" );
- rv = False;
- }
- XklConfigRecDestroy( &data );
- return rv;
+gboolean
+xkl_config_rec_get_from_server(XklConfigRec * data, XklEngine * engine)
+{
+ return xkl_config_rec_get_full_from_server(NULL, data, engine);
+}
+
+gboolean
+xkl_config_rec_get_from_backup(XklConfigRec * data, XklEngine * engine)
+{
+ return xkl_config_rec_get_from_root_window_property(data,
+ xkl_engine_priv
+ (engine,
+ backup_config_atom),
+ NULL, engine);
+}
+
+gboolean
+xkl_backup_names_prop(XklEngine * engine)
+{
+ gboolean rv = TRUE;
+ gchar *rf = NULL;
+ XklConfigRec data;
+ gboolean cgp = FALSE;
+
+ xkl_config_rec_init(&data);
+ if (xkl_config_rec_get_from_root_window_property
+ (&data, xkl_engine_priv(engine, backup_config_atom), NULL,
+ engine)) {
+ xkl_config_rec_destroy(&data);
+ return TRUE;
+ }
+ /* "backup" property is not defined */
+ xkl_config_rec_reset(&data);
+ cgp = xkl_config_rec_get_full_from_server(&rf, &data, engine);
+
+ if (cgp) {
+ if (!xkl_config_rec_set_to_root_window_property
+ (&data, xkl_engine_priv(engine, backup_config_atom),
+ rf, engine)) {
+ xkl_debug(150,
+ "Could not backup the configuration");
+ rv = FALSE;
+ }
+ if (rf != NULL)
+ g_free(rf);
+ } else {
+ xkl_debug(150,
+ "Could not get the configuration for backup");
+ rv = FALSE;
+ }
+ xkl_config_rec_destroy(&data);
+ return rv;
}
-Bool XklRestoreNamesProp( void )
+gboolean
+xkl_restore_names_prop(XklEngine * engine)
{
- Bool rv = True;
- char *rf = NULL;
- XklConfigRec data;
-
- XklConfigRecInit( &data );
- if( !XklGetNamesProp( xklVTable->backupConfigAtom, NULL, &data ) )
- {
- XklConfigRecDestroy( &data );
- return False;
- }
-
- if( !XklSetNamesProp( xklVTable->baseConfigAtom, rf, &data ) )
- {
- XklDebug( 150, "Could not backup the configuration" );
- rv = False;
- }
- XklConfigRecDestroy( &data );
- return rv;
+ gboolean rv = TRUE;
+ gchar *rf = NULL;
+ XklConfigRec data;
+
+ xkl_config_rec_init(&data);
+ if (!xkl_config_rec_get_from_root_window_property
+ (&data, xkl_engine_priv(engine, backup_config_atom), NULL,
+ engine)) {
+ xkl_config_rec_destroy(&data);
+ return FALSE;
+ }
+
+ if (!xkl_config_rec_set_to_root_window_property
+ (&data, xkl_engine_priv(engine, base_config_atom), rf,
+ engine)) {
+ xkl_debug(150, "Could not backup the configuration");
+ rv = FALSE;
+ }
+ xkl_config_rec_destroy(&data);
+ return rv;
}
-Bool XklGetNamesProp( Atom rulesAtom,
- char **rulesFileOut, XklConfigRecPtr data )
+gboolean
+xkl_config_rec_get_from_root_window_property(XklConfigRec * data,
+ Atom rules_atom,
+ gchar ** rules_file_out,
+ XklEngine * engine)
{
- Atom realPropType;
- int fmt;
- unsigned long nitems, extraBytes;
- char *propData = NULL, *out;
- Status rtrn;
-
- /* no such atom! */
- if( rulesAtom == None ) /* property cannot exist */
- {
- _xklLastErrorMsg = "Could not find the atom";
- return False;
- }
-
- rtrn =
- XGetWindowProperty( _xklDpy, _xklRootWindow, rulesAtom, 0L,
- _XKB_RF_NAMES_PROP_MAXLEN, False, XA_STRING,
- &realPropType, &fmt, &nitems, &extraBytes,
- ( unsigned char ** ) ( void * ) &propData );
- /* property not found! */
- if( rtrn != Success )
- {
- _xklLastErrorMsg = "Could not get the property";
- return False;
- }
- /* set rules file to "" */
- if( rulesFileOut )
- *rulesFileOut = NULL;
-
- /* has to be array of strings */
- if( ( extraBytes > 0 ) || ( realPropType != XA_STRING ) || ( fmt != 8 ) )
- {
- if( propData )
- XFree( propData );
- _xklLastErrorMsg = "Wrong property format";
- return False;
- }
-
- if( !propData )
- {
- _xklLastErrorMsg = "No properties returned";
- return False;
- }
-
- /* rules file */
- out = propData;
- if( out && ( *out ) && rulesFileOut )
- *rulesFileOut = strdup( out );
- out += strlen( out ) + 1;
-
- /* if user is interested in rules only - don't waste the time */
- if( !data )
- {
- XFree( propData );
- return True;
- }
-
- if( ( out - propData ) < nitems )
- {
- if( *out )
- data->model = strdup( out );
- out += strlen( out ) + 1;
- }
-
- if( ( out - propData ) < nitems )
- {
- _XklConfigRecSplitLayouts( data, out );
- out += strlen( out ) + 1;
- }
-
- if( ( out - propData ) < nitems )
- {
- int i;
- char **theLayout, **theVariant;
- _XklConfigRecSplitVariants( data, out );
- /*
- Now have to ensure that number of variants matches the number of layouts
- The 'remainder' is filled with NULLs (not ""s!)
- */
- if( data->numVariants < data->numLayouts )
- {
- data->variants =
- realloc( data->variants, data->numLayouts * sizeof( char * ) );
- memset( data->variants + data->numVariants, 0,
- ( data->numLayouts - data->numVariants ) * sizeof( char * ) );
- data->numVariants = data->numLayouts;
- }
- /* take variants from layouts like ru(winkeys) */
- theLayout = data->layouts;
- theVariant = data->variants;
- for( i = data->numLayouts; --i >= 0; theLayout++, theVariant++ )
- {
- if( *theLayout != NULL )
- {
- char *varstart = strchr( *theLayout, '(' );
- if( varstart != NULL )
- {
- char *varend = strchr( varstart, ')' );
- if( varend != NULL )
- {
- int varlen = varend - varstart;
- int laylen = varstart - *theLayout;
- /* I am not sure - but I assume variants in layout have priority */
- char *var = *theVariant = ( *theVariant != NULL ) ?
- realloc( *theVariant, varlen ) : malloc( varlen );
- memcpy( var, varstart + 1, --varlen );
- var[varlen] = '\0';
-
- ( (char*)realloc( *theLayout, laylen + 1 ) )[laylen] = '\0';
- }
- }
- }
- }
- out += strlen( out ) + 1;
- }
-
- if( ( out - propData ) < nitems )
- {
- _XklConfigRecSplitOptions( data, out );
-/* out += strlen( out ) + 1; */
- }
- XFree( propData );
- return True;
+ Atom real_prop_type;
+ int fmt;
+ unsigned long nitems, extra_bytes;
+ char *prop_data = NULL, *out;
+ Status rtrn;
+
+ /* no such atom! */
+ if (rules_atom == None) { /* property cannot exist */
+ xkl_last_error_message = "Could not find the atom";
+ return FALSE;
+ }
+
+ rtrn =
+ XGetWindowProperty(xkl_engine_get_display(engine),
+ xkl_engine_priv(engine, root_window),
+ rules_atom, 0L, XKB_RF_NAMES_PROP_MAXLEN,
+ False, XA_STRING, &real_prop_type, &fmt,
+ &nitems, &extra_bytes,
+ (unsigned char **) (void *) &prop_data);
+ /* property not found! */
+ if (rtrn != Success) {
+ xkl_last_error_message = "Could not get the property";
+ return FALSE;
+ }
+ /* set rules file to "" */
+ if (rules_file_out)
+ *rules_file_out = NULL;
+
+ /* has to be array of strings */
+ if ((extra_bytes > 0) || (real_prop_type != XA_STRING)
+ || (fmt != 8)) {
+ if (prop_data)
+ XFree(prop_data);
+ xkl_last_error_message = "Wrong property format";
+ return FALSE;
+ }
+
+ if (!prop_data) {
+ xkl_last_error_message = "No properties returned";
+ return FALSE;
+ }
+
+ /* rules file */
+ out = prop_data;
+ if (out && (*out) && rules_file_out)
+ *rules_file_out = g_strdup(out);
+ out += strlen(out) + 1;
+
+ /* if user is interested in rules only - don't waste the time */
+ if (!data) {
+ XFree(prop_data);
+ return TRUE;
+ }
+
+ if ((out - prop_data) < nitems) {
+ if (*out)
+ data->model = g_strdup(out);
+ out += strlen(out) + 1;
+ }
+
+ if ((out - prop_data) < nitems) {
+ xkl_config_rec_split_layouts(data, out);
+ out += strlen(out) + 1;
+ }
+
+ if ((out - prop_data) < nitems) {
+ gint nv, nl;
+ gchar **layout, **variant;
+ xkl_config_rec_split_variants(data, out);
+ /*
+ Now have to ensure that number of variants matches the number of layouts
+ The 'remainder' is filled with NULLs (not ""s!)
+ */
+
+ nv = g_strv_length(data->variants);
+ nl = g_strv_length(data->layouts);
+ if (nv < nl) {
+ data->variants = g_realloc(data->variants,
+ (nl +
+ 1) * sizeof(char *));
+ memset(data->variants + nv + 1, 0,
+ (nl - nv) * sizeof(char *));
+ }
+ /* take variants from layouts like ru(winkeys) */
+ layout = data->layouts;
+ variant = data->variants;
+ while (*layout != NULL && *variant != NULL) {
+ gchar *varstart = g_strstr_len(*layout, -1, "(");
+ if (varstart != NULL) {
+ gchar *varend =
+ g_strstr_len(varstart, -1, ")");
+ if (varend != NULL) {
+ gint varlen = varend - varstart;
+ gint laylen = varstart - *layout;
+ /* I am not sure - but I assume variants in layout have priority */
+ gchar *var = *variant =
+ (*variant !=
+ NULL) ? g_realloc(*variant,
+ varlen) :
+ g_new(gchar, varlen);
+ memcpy(var, varstart + 1,
+ --varlen);
+ var[varlen] = '\0';
+ /* Resize the original layout */
+ ((char *)
+ g_realloc(*layout,
+ laylen + 1))[laylen] =
+ '\0';
+ }
+ }
+ layout++;
+ variant++;
+ }
+ out += strlen(out) + 1;
+ }
+
+ if ((out - prop_data) < nitems) {
+ xkl_config_rec_split_options(data, out);
+ }
+ XFree(prop_data);
+ return TRUE;
}
/* taken from XFree86 maprules.c */
-Bool XklSetNamesProp( Atom rulesAtom,
- char *rulesFile, const XklConfigRecPtr data )
+gboolean
+xkl_config_rec_set_to_root_window_property(const XklConfigRec * data,
+ Atom rules_atom,
+ gchar * rules_file,
+ XklEngine * engine)
{
- int len, rv;
- char *pval;
- char *next;
- char *allLayouts = _XklConfigRecMergeLayouts( data );
- char *allVariants = _XklConfigRecMergeVariants( data );
- char *allOptions = _XklConfigRecMergeOptions( data );
-
- len = ( rulesFile ? strlen( rulesFile ) : 0 );
- len += ( data->model ? strlen( data->model ) : 0 );
- len += ( allLayouts ? strlen( allLayouts ) : 0 );
- len += ( allVariants ? strlen( allVariants ) : 0 );
- len += ( allOptions ? strlen( allOptions ) : 0 );
- if( len < 1 )
- return True;
-
- len += 5; /* trailing NULs */
-
- pval = next = ( char * ) malloc( len + 1 );
- if( !pval )
- {
- _xklLastErrorMsg = "Could not allocate buffer";
- if ( allLayouts != NULL ) free( allLayouts );
- if ( allVariants != NULL ) free( allVariants );
- if ( allOptions != NULL ) free( allOptions );
- return False;
- }
- if( rulesFile )
- {
- strcpy( next, rulesFile );
- next += strlen( rulesFile );
- }
- *next++ = '\0';
- if( data->model )
- {
- strcpy( next, data->model );
- next += strlen( data->model );
- }
- *next++ = '\0';
- if( data->layouts )
- {
- strcpy( next, allLayouts );
- next += strlen( allLayouts );
- }
- *next++ = '\0';
- if( data->variants )
- {
- strcpy( next, allVariants );
- next += strlen( allVariants );
- }
- *next++ = '\0';
- if( data->options )
- {
- strcpy( next, allOptions );
- next += strlen( allOptions );
- }
- *next++ = '\0';
- if( ( next - pval ) != len )
- {
- XklDebug( 150, "Illegal final position: %d/%d\n", ( next - pval ), len );
- if ( allLayouts != NULL ) free( allLayouts );
- if ( allVariants != NULL ) free( allVariants );
- if ( allOptions != NULL ) free( allOptions );
- free( pval );
- _xklLastErrorMsg = "Internal property parsing error";
- return False;
- }
-
- rv = XChangeProperty( _xklDpy, _xklRootWindow, rulesAtom, XA_STRING, 8,
- PropModeReplace, ( unsigned char * ) pval, len );
- XSync( _xklDpy, False );
+ gint len, rv;
+ gchar *pval;
+ gchar *next;
+ gchar *all_layouts = xkl_config_rec_merge_layouts(data);
+ gchar *all_variants = xkl_config_rec_merge_variants(data);
+ gchar *all_options = xkl_config_rec_merge_options(data);
+
+ len = (rules_file ? strlen(rules_file) : 0);
+ len += (data->model ? strlen(data->model) : 0);
+ len += (all_layouts ? strlen(all_layouts) : 0);
+ len += (all_variants ? strlen(all_variants) : 0);
+ len += (all_options ? strlen(all_options) : 0);
+ if (len < 1)
+ return TRUE;
+
+ len += 5; /* trailing NULs */
+
+ pval = next = g_new(char, len + 1);
+ if (!pval) {
+ xkl_last_error_message = "Could not allocate buffer";
+ if (all_layouts != NULL)
+ g_free(all_layouts);
+ if (all_variants != NULL)
+ g_free(all_variants);
+ if (all_options != NULL)
+ g_free(all_options);
+ return FALSE;
+ }
+ if (rules_file) {
+ strcpy(next, rules_file);
+ next += strlen(rules_file);
+ }
+ *next++ = '\0';
+ if (data->model) {
+ strcpy(next, data->model);
+ next += strlen(data->model);
+ }
+ *next++ = '\0';
+ if (data->layouts) {
+ strcpy(next, all_layouts);
+ next += strlen(all_layouts);
+ }
+ *next++ = '\0';
+ if (data->variants) {
+ strcpy(next, all_variants);
+ next += strlen(all_variants);
+ }
+ *next++ = '\0';
+ if (data->options) {
+ strcpy(next, all_options);
+ next += strlen(all_options);
+ }
+ *next++ = '\0';
+ if ((next - pval) != len) {
+ xkl_debug(150, "Illegal final position: %d/%d\n",
+ (next - pval), len);
+ if (all_layouts != NULL)
+ g_free(all_layouts);
+ if (all_variants != NULL)
+ g_free(all_variants);
+ if (all_options != NULL)
+ g_free(all_options);
+ g_free(pval);
+ xkl_last_error_message = "Internal property parsing error";
+ return FALSE;
+ }
+
+ Display *display = xkl_engine_get_display(engine);
+ rv = XChangeProperty(display, xkl_engine_priv(engine, root_window),
+ rules_atom, XA_STRING, 8, PropModeReplace,
+ (unsigned char *) pval, len);
+ XSync(display, False);
#if 0
- for( i = len - 1; --i >= 0; )
- if( pval[i] == '\0' )
- pval[i] = '?';
- XklDebug( 150, "Stored [%s] of length %d to [%s] of %X: %d\n", pval, len,
- propName, _xklRootWindow, rv );
+ for (i = len - 1; --i >= 0;)
+ if (pval[i] == '\0')
+ pval[i] = '?';
+ XklDebug(150, "Stored [%s] of length %d to [%s] of %X: %d\n", pval,
+ len, propName, _xklRootWindow, rv);
#endif
- if ( allLayouts != NULL ) free( allLayouts );
- if ( allVariants != NULL ) free( allVariants );
- if ( allOptions != NULL ) free( allOptions );
- free( pval );
- return True;
+ if (all_layouts != NULL)
+ g_free(all_layouts);
+ if (all_variants != NULL)
+ g_free(all_variants);
+ if (all_options != NULL)
+ g_free(all_options);
+ g_free(pval);
+ return TRUE;
}
diff --git a/libxklavier/xklavier_toplevel.c b/libxklavier/xklavier_toplevel.c
new file mode 100644
index 0000000..ab19bbb
--- /dev/null
+++ b/libxklavier/xklavier_toplevel.c
@@ -0,0 +1,343 @@
+#include <time.h>
+
+#include <X11/Xmd.h>
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include "xklavier_private.h"
+
+Window xkl_toplevel_window_prev;
+
+void
+xkl_engine_set_toplevel_window_transparent(XklEngine * engine,
+ Window toplevel_win,
+ gboolean transparent)
+{
+ gboolean oldval;
+
+ oldval =
+ xkl_engine_is_toplevel_window_transparent(engine,
+ toplevel_win);
+ xkl_debug(150, "toplevel_win " WINID_FORMAT " was %stransparent\n",
+ toplevel_win, oldval ? "" : "not ");
+ if (transparent && !oldval) {
+ CARD32 prop = 1;
+ XChangeProperty(xkl_engine_get_display(engine),
+ toplevel_win,
+ xkl_engine_priv(engine, atoms)
+ [XKLAVIER_TRANSPARENT], XA_INTEGER, 32,
+ PropModeReplace,
+ (const unsigned char *) &prop, 1);
+ } else if (!transparent && oldval) {
+ XDeleteProperty(xkl_engine_get_display(engine),
+ toplevel_win,
+ xkl_engine_priv(engine, atoms)
+ [XKLAVIER_TRANSPARENT]);
+ }
+}
+
+/*
+ * "Adds" app window to the set of managed windows.
+ * Actually, no data structures involved. The only thing we do is save app state
+ * and register ourselves us listeners.
+ * Note: User's callback is called
+ */
+void
+xkl_engine_add_toplevel_window(XklEngine * engine, Window toplevel_win,
+ Window parent,
+ gboolean ignore_existing_state,
+ XklState * init_state)
+{
+ XklState state = *init_state;
+ gint default_group_to_use = -1;
+
+ if (toplevel_win == xkl_engine_priv(engine, root_window))
+ xkl_debug(150, "??? root app win ???\n");
+
+ xkl_debug(150,
+ "Trying to add window " WINID_FORMAT
+ "/%s with group %d\n", toplevel_win,
+ xkl_get_debug_window_title(engine, toplevel_win),
+ init_state->group);
+
+ if (!ignore_existing_state) {
+ gboolean have_state =
+ xkl_engine_get_toplevel_window_state(engine,
+ toplevel_win,
+ &state);
+
+ if (have_state) {
+ xkl_debug(150,
+ "The window " WINID_FORMAT
+ " does not require to be added, it already has the xklavier state \n",
+ toplevel_win);
+ return;
+ }
+ }
+
+ g_signal_emit_by_name(engine, "new-toplevel_window", toplevel_win,
+ parent, &default_group_to_use);
+
+ if (default_group_to_use == -1)
+ default_group_to_use =
+ xkl_engine_priv(engine, default_group);
+
+ if (default_group_to_use != -1)
+ state.group = default_group_to_use;
+
+ xkl_engine_save_toplevel_window_state(engine, toplevel_win,
+ &state);
+ xkl_engine_select_input_merging(engine, toplevel_win,
+ FocusChangeMask |
+ PropertyChangeMask);
+
+ if (default_group_to_use != -1) {
+ if (xkl_engine_priv(engine, curr_toplvl_win) ==
+ toplevel_win) {
+ if ((xkl_engine_priv(engine, secondary_groups_mask)
+ & (1 << default_group_to_use)) != 0)
+ xkl_engine_allow_one_switch_to_secondary_group
+ (engine);
+ xkl_engine_lock_group(engine,
+ default_group_to_use);
+ }
+ }
+
+ if (parent == (Window) NULL)
+ parent =
+ xkl_engine_get_registered_parent(engine, toplevel_win);
+
+ xkl_debug(150, "done\n");
+}
+
+/*
+ * Checks the window and goes up
+ */
+gboolean
+xkl_engine_find_toplevel_window_bottom_to_top(XklEngine * engine,
+ Window win,
+ Window * toplevel_win_out)
+{
+ Window parent = (Window) NULL, rwin = (Window) NULL, *children =
+ NULL;
+ guint num = 0;
+
+ if (win == (Window) NULL
+ || win == xkl_engine_priv(engine, root_window)) {
+ *toplevel_win_out = win;
+ xkl_last_error_message = "The window is either 0 or root";
+ return FALSE;
+ }
+
+ if (xkl_engine_if_window_has_wm_state(engine, win)) {
+ *toplevel_win_out = win;
+ return TRUE;
+ }
+
+ xkl_engine_priv(engine, last_error_code) =
+ xkl_engine_query_tree(engine, win, &rwin, &parent, &children,
+ &num);
+
+ if (xkl_engine_priv(engine, last_error_code) != Success) {
+ *toplevel_win_out = (Window) NULL;
+ return FALSE;
+ }
+
+ if (children != NULL)
+ XFree(children);
+
+ return xkl_engine_find_toplevel_window_bottom_to_top(engine,
+ parent,
+ toplevel_win_out);
+}
+
+/*
+ * Recursively finds "App window" (window with WM_STATE) for given window.
+ * First, checks the window itself
+ * Then, for first level of recursion, checks childen,
+ * Then, goes to parent.
+ * NOTE: root window cannot be "App window" under normal circumstances
+ */
+gboolean
+xkl_engine_find_toplevel_window(XklEngine * engine, Window win,
+ Window * toplevel_win_out)
+{
+ Window parent = (Window) NULL,
+ rwin = (Window) NULL, *children = NULL, *child;
+ guint num = 0;
+ gboolean rv;
+
+ if (win == (Window) NULL
+ || win == xkl_engine_priv(engine, root_window)) {
+ *toplevel_win_out = (Window) NULL;
+ xkl_last_error_message = "The window is either 0 or root";
+ xkl_debug(150,
+ "Window " WINID_FORMAT
+ " is either 0 or root so could not get the app window for it\n",
+ win);
+ return FALSE;
+ }
+
+ if (xkl_engine_if_window_has_wm_state(engine, win)) {
+ *toplevel_win_out = win;
+ return TRUE;
+ }
+
+ xkl_engine_priv(engine, last_error_code) =
+ xkl_engine_query_tree(engine, win, &rwin, &parent, &children,
+ &num);
+
+ if (xkl_engine_priv(engine, last_error_code) != Success) {
+ *toplevel_win_out = (Window) NULL;
+ xkl_debug(150,
+ "Could not get tree for window " WINID_FORMAT
+ " so could not get the app window for it\n",
+ win);
+ return FALSE;
+ }
+
+ /*
+ * Here we first check the children (in case win is just above some "App Window")
+ * and then go upstairs
+ */
+ child = children;
+ while (num) {
+ if (xkl_engine_if_window_has_wm_state(engine, *child)) {
+ *toplevel_win_out = *child;
+ if (children != NULL)
+ XFree(children);
+ return TRUE;
+ }
+ child++;
+ num--;
+ }
+
+ if (children != NULL)
+ XFree(children);
+
+ rv = xkl_engine_find_toplevel_window_bottom_to_top(engine, parent,
+ toplevel_win_out);
+
+ if (!rv)
+ xkl_debug(200,
+ "Could not get the app window for " WINID_FORMAT
+ "/%s\n", win, xkl_get_debug_window_title(engine,
+ win));
+
+ return rv;
+}
+
+/*
+ * Gets the state from the window property
+ */
+gboolean
+xkl_engine_get_toplevel_window_state(XklEngine * engine,
+ Window toplevel_win,
+ XklState * state_out)
+{
+ Atom type_ret;
+ int format_ret;
+ unsigned long nitems, rest;
+ CARD32 *prop = NULL;
+ gboolean ret = FALSE;
+
+ gint grp = -1;
+ guint inds = 0;
+
+ if ((XGetWindowProperty
+ (xkl_engine_get_display(engine), toplevel_win,
+ xkl_engine_priv(engine, atoms)[XKLAVIER_STATE], 0L,
+ XKLAVIER_STATE_PROP_LENGTH, False, XA_INTEGER, &type_ret,
+ &format_ret, &nitems, &rest,
+ (unsigned char **) (void *) &prop) == Success)
+ && (type_ret == XA_INTEGER) && (format_ret == 32)) {
+ grp = prop[0];
+ if (grp >= xkl_engine_get_num_groups(engine) || grp < 0)
+ grp = 0;
+
+ inds = prop[1];
+
+ if (state_out != NULL) {
+ state_out->group = grp;
+ state_out->indicators = inds;
+ }
+ if (prop != NULL)
+ XFree(prop);
+
+ ret = TRUE;
+ }
+
+ if (ret)
+ xkl_debug(150,
+ "Appwin " WINID_FORMAT
+ ", '%s' has the group %d, indicators %X\n",
+ toplevel_win,
+ xkl_get_debug_window_title(engine, toplevel_win),
+ grp, inds);
+ else
+ xkl_debug(150,
+ "Appwin " WINID_FORMAT
+ ", '%s' does not have state\n", toplevel_win,
+ xkl_get_debug_window_title(engine,
+ toplevel_win));
+
+ return ret;
+}
+
+/*
+ * Deletes the state from the window properties
+ */
+void
+xkl_engine_remove_toplevel_window_state(XklEngine * engine,
+ Window toplevel_win)
+{
+ XDeleteProperty(xkl_engine_get_display(engine), toplevel_win,
+ xkl_engine_priv(engine, atoms)[XKLAVIER_STATE]);
+}
+
+/*
+ * Saves the state into the window properties
+ */
+void
+xkl_engine_save_toplevel_window_state(XklEngine * engine,
+ Window toplevel_win,
+ XklState * state)
+{
+ CARD32 prop[XKLAVIER_STATE_PROP_LENGTH];
+
+ prop[0] = state->group;
+ prop[1] = state->indicators;
+
+ XChangeProperty(xkl_engine_get_display(engine), toplevel_win,
+ xkl_engine_priv(engine, atoms)[XKLAVIER_STATE],
+ XA_INTEGER, 32, PropModeReplace,
+ (const unsigned char *) prop,
+ XKLAVIER_STATE_PROP_LENGTH);
+
+ xkl_debug(160,
+ "Saved the group %d, indicators %X for appwin "
+ WINID_FORMAT "\n", state->group, state->indicators,
+ toplevel_win);
+}
+
+gboolean
+xkl_engine_is_toplevel_window_transparent(XklEngine * engine,
+ Window toplevel_win)
+{
+ Atom type_ret;
+ int format_ret;
+ unsigned long nitems, rest;
+ CARD32 *prop = NULL;
+ if ((XGetWindowProperty
+ (xkl_engine_get_display(engine), toplevel_win,
+ xkl_engine_priv(engine, atoms)[XKLAVIER_TRANSPARENT], 0L, 1,
+ False, XA_INTEGER, &type_ret, &format_ret, &nitems, &rest,
+ (unsigned char **) (void *) &prop) == Success)
+ && (type_ret == XA_INTEGER) && (format_ret == 32)) {
+ if (prop != NULL)
+ XFree(prop);
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/libxklavier/xklavier_util.c b/libxklavier/xklavier_util.c
index d87247e..c0de9a5 100644
--- a/libxklavier/xklavier_util.c
+++ b/libxklavier/xklavier_util.c
@@ -1,271 +1,309 @@
#include <time.h>
+#include <string.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <X11/Xlibint.h>
#include "xklavier_private.h"
-XklState *XklGetCurrentState( )
+XklState *
+xkl_engine_get_current_state(XklEngine * engine)
{
- return &_xklCurState;
+ return &xkl_engine_priv(engine, curr_state);
}
-const char *XklGetLastError( )
+const gchar *
+xkl_get_last_error()
{
- return _xklLastErrorMsg;
+ return xkl_last_error_message;
}
-unsigned char *XklGetWindowTitle( Window w )
+gchar *
+xkl_engine_get_window_title(XklEngine * engine, Window w)
{
- Atom type_ret;
- int format_ret;
- unsigned long nitems, rest;
- unsigned char *prop;
-
- if( Success == XGetWindowProperty( _xklDpy, w, _xklAtoms[WM_NAME], 0L,
- -1L, False, XA_STRING, &type_ret,
- &format_ret, &nitems, &rest, &prop ) )
- return prop;
- else
- return NULL;
+ Atom type_ret;
+ int format_ret;
+ unsigned long nitems, rest;
+ unsigned char *prop;
+
+ if (Success ==
+ XGetWindowProperty(xkl_engine_get_display(engine), w,
+ xkl_engine_priv(engine, atoms)[WM_NAME], 0L,
+ -1L, False, XA_STRING, &type_ret,
+ &format_ret, &nitems, &rest, &prop))
+ return (gchar *) prop;
+ else
+ return NULL;
}
-Bool XklIsSameApp( Window win1, Window win2 )
+gboolean
+xkl_engine_is_window_from_same_toplevel_window(XklEngine * engine,
+ Window win1, Window win2)
{
- Window app1, app2;
- return _XklGetAppWindow( win1, &app1 ) &&
- _XklGetAppWindow( win2, &app2 ) && app1 == app2;
+ Window app1, app2;
+ return xkl_engine_find_toplevel_window(engine, win1, &app1) &&
+ xkl_engine_find_toplevel_window(engine, win2, &app2)
+ && app1 == app2;
}
-Bool XklGetState( Window win, XklState * state_return )
+gboolean
+xkl_engine_get_state(XklEngine * engine, Window win, XklState * state_out)
{
- Window appWin;
+ Window app_win;
- if( !_XklGetAppWindow( win, &appWin ) )
- {
- if( state_return != NULL )
- state_return->group = -1;
- return False;
- }
+ if (!xkl_engine_find_toplevel_window(engine, win, &app_win)) {
+ if (state_out != NULL)
+ state_out->group = -1;
+ return FALSE;
+ }
- return _XklGetAppState( appWin, state_return );
+ return xkl_engine_get_toplevel_window_state(engine, app_win,
+ state_out);
}
-void XklDelState( Window win )
+void
+xkl_engine_delete_state(XklEngine * engine, Window win)
{
- Window appWin;
+ Window app_win;
- if( _XklGetAppWindow( win, &appWin ) )
- _XklDelAppState( appWin );
+ if (xkl_engine_find_toplevel_window(engine, win, &app_win))
+ xkl_engine_remove_toplevel_window_state(engine, app_win);
}
-void XklSaveState( Window win, XklState * state )
+void
+xkl_engine_save_state(XklEngine * engine, Window win, XklState * state)
{
- Window appWin;
+ Window app_win;
- if( !( _xklListenerType & XKLL_MANAGE_WINDOW_STATES ) )
- return;
+ if (!
+ (xkl_engine_priv(engine, listener_type) &
+ XKLL_MANAGE_WINDOW_STATES))
+ return;
- if( _XklGetAppWindow( win, &appWin ) )
- _XklSaveAppState( appWin, state );
+ if (xkl_engine_find_toplevel_window(engine, win, &app_win))
+ xkl_engine_save_toplevel_window_state(engine, app_win,
+ state);
}
-/**
+/*
* Prepares the name of window suitable for debugging (32characters long).
*/
-char *_XklGetDebugWindowTitle( Window win )
+gchar *
+xkl_get_debug_window_title(XklEngine * engine, Window win)
{
- static char sname[33];
- unsigned char *name;
- strcpy( sname, "NULL" );
- if( win != ( Window ) NULL )
- {
- name = XklGetWindowTitle( win );
- if( name != NULL )
- {
- snprintf( sname, sizeof( sname ), "%.32s", name );
- free( name );
- }
- }
- return sname;
+ static gchar sname[33];
+ gchar *name;
+ strcpy(sname, "NULL");
+ if (win != (Window) NULL) {
+ name = xkl_engine_get_window_title(engine, win);
+ if (name != NULL) {
+ snprintf(sname, sizeof(sname), "%.32s", name);
+ g_free(name);
+ }
+ }
+ return sname;
}
-Window XklGetCurrentWindow( )
+Window
+xkl_engine_get_current_window(XklEngine * engine)
{
- return _xklCurClient;
+ return xkl_engine_priv(engine, curr_toplvl_win);
}
-/**
+/*
* Loads subtree.
* All the windows with WM_STATE are added.
* All the windows within level 0 are listened for focus and property
*/
-Bool _XklLoadSubtree( Window window, int level, XklState * initState )
+gboolean
+xkl_engine_load_subtree(XklEngine * engine, Window window, gint level,
+ XklState * init_state)
{
- Window rwin = ( Window ) NULL,
- parent = ( Window ) NULL, *children = NULL, *child;
- unsigned int num = 0;
- Bool retval = True;
-
- _xklLastErrorCode =
- _XklStatusQueryTree( _xklDpy, window, &rwin, &parent, &children, &num );
-
- if( _xklLastErrorCode != Success )
- {
- return False;
- }
-
- child = children;
- while( num )
- {
- if( _XklHasWmState( *child ) )
- {
- XklDebug( 160, "Window " WINID_FORMAT " '%s' has WM_STATE so we'll add it\n",
- *child, _XklGetDebugWindowTitle( *child ) );
- _XklAddAppWindow( *child, window, True, initState );
- } else
- {
- XklDebug( 200, "Window " WINID_FORMAT " '%s' does not have have WM_STATE so we'll not add it\n",
- *child, _XklGetDebugWindowTitle( *child ) );
-
- if( level == 0 )
- {
- XklDebug( 200, "But we are at level 0 so we'll spy on it\n" );
- _XklSelectInputMerging( *child,
- FocusChangeMask | PropertyChangeMask );
- } else
- XklDebug( 200, "And we are at level %d so we'll not spy on it\n",
- level );
-
- retval = _XklLoadSubtree( *child, level + 1, initState );
- }
-
- child++;
- num--;
- }
-
- if( children != NULL )
- XFree( children );
-
- return retval;
+ Window rwin = (Window) NULL,
+ parent = (Window) NULL, *children = NULL, *child;
+ guint num = 0;
+ gboolean retval = True;
+
+ xkl_engine_priv(engine, last_error_code) =
+ xkl_engine_query_tree(engine, window, &rwin, &parent,
+ &children, &num);
+
+ if (xkl_engine_priv(engine, last_error_code) != Success) {
+ return FALSE;
+ }
+
+ child = children;
+ while (num) {
+ if (xkl_engine_if_window_has_wm_state(engine, *child)) {
+ xkl_debug(160,
+ "Window " WINID_FORMAT
+ " '%s' has WM_STATE so we'll add it\n",
+ *child,
+ xkl_get_debug_window_title(engine,
+ *child));
+ xkl_engine_add_toplevel_window(engine, *child,
+ window, TRUE,
+ init_state);
+ } else {
+ xkl_debug(200,
+ "Window " WINID_FORMAT
+ " '%s' does not have have WM_STATE so we'll not add it\n",
+ *child,
+ xkl_get_debug_window_title(engine,
+ *child));
+
+ if (level == 0) {
+ xkl_debug(200,
+ "But we are at level 0 so we'll spy on it\n");
+ xkl_engine_select_input_merging(engine,
+ *child,
+ FocusChangeMask
+ |
+ PropertyChangeMask);
+ } else
+ xkl_debug(200,
+ "And we are at level %d so we'll not spy on it\n",
+ level);
+
+ retval =
+ xkl_engine_load_subtree(engine, *child,
+ level + 1, init_state);
+ }
+
+ child++;
+ num--;
+ }
+
+ if (children != NULL)
+ XFree(children);
+
+ return retval;
}
-/**
+/*
* Checks whether given window has WM_STATE property (i.e. "App window").
*/
-Bool _XklHasWmState( Window win )
-{ /* ICCCM 4.1.3.1 */
- Atom type = None;
- int format;
- unsigned long nitems;
- unsigned long after;
- unsigned char *data = NULL; /* Helps in the case of BadWindow error */
-
- XGetWindowProperty( _xklDpy, win, _xklAtoms[WM_STATE], 0, 0, False,
- _xklAtoms[WM_STATE], &type, &format, &nitems, &after,
- &data );
- if( data != NULL )
- XFree( data ); /* To avoid an one-byte memory leak because after successfull return
- * data array always contains at least one nul byte (NULL-equivalent) */
- return type != None;
+gboolean
+xkl_engine_if_window_has_wm_state(XklEngine * engine, Window win)
+{ /* ICCCM 4.1.3.1 */
+ Atom type = None;
+ int format;
+ unsigned long nitems;
+ unsigned long after;
+ unsigned char *data = NULL; /* Helps in the case of BadWindow error */
+
+ XGetWindowProperty(xkl_engine_get_display(engine), win,
+ xkl_engine_priv(engine, atoms)[WM_STATE], 0, 0,
+ False, xkl_engine_priv(engine, atoms)[WM_STATE],
+ &type, &format, &nitems, &after, &data);
+ if (data != NULL)
+ XFree(data); /* To avoid an one-byte memory leak because after successfull return
+ * data array always contains at least one nul byte (NULL-equivalent) */
+ return type != None;
}
-/**
+/*
* Finds out the official parent window (accortind to XQueryTree)
*/
-Window _XklGetRegisteredParent( Window win )
+Window
+xkl_engine_get_registered_parent(XklEngine * engine, Window win)
{
- Window parent = ( Window ) NULL, rw = ( Window ) NULL, *children = NULL;
- unsigned int nchildren = 0;
+ Window parent = (Window) NULL, rw = (Window) NULL, *children =
+ NULL;
+ guint nchildren = 0;
- _xklLastErrorCode =
- _XklStatusQueryTree( _xklDpy, win, &rw, &parent, &children, &nchildren );
+ xkl_engine_priv(engine, last_error_code) =
+ xkl_engine_query_tree(engine, win, &rw, &parent, &children,
+ &nchildren);
- if( children != NULL )
- XFree( children );
+ if (children != NULL)
+ XFree(children);
- return _xklLastErrorCode == Success ? parent : ( Window ) NULL;
+ return xkl_engine_priv(engine, last_error_code) ==
+ Success ? parent : (Window) NULL;
}
/**
* Make sure about the result. Origial XQueryTree is pretty stupid beast:)
*/
-Status _XklStatusQueryTree( Display * display,
- Window w,
- Window * root_return,
- Window * parent_return,
- Window ** children_return,
- unsigned int *nchildren_return )
+Status
+xkl_engine_query_tree(XklEngine * engine, Window w,
+ Window * root_out,
+ Window * parent_out,
+ Window ** children_out, guint * nchildren_out)
{
- Bool result;
-
- result = ( Bool ) XQueryTree( display,
- w,
- root_return,
- parent_return,
- children_return, nchildren_return );
- if( !result )
- {
- XklDebug( 160,
- "Could not get tree info for window " WINID_FORMAT ": %d\n", w,
- result );
- _xklLastErrorMsg = "Could not get the tree info";
- }
-
- return result ? Success : FirstExtensionError;
+ gboolean result;
+ unsigned int nc;
+
+ result = (gboolean) XQueryTree(xkl_engine_get_display(engine),
+ w,
+ root_out,
+ parent_out, children_out, &nc);
+ *nchildren_out = nc;
+
+ if (!result) {
+ xkl_debug(160,
+ "Could not get tree info for window "
+ WINID_FORMAT ": %d\n", w, result);
+ xkl_last_error_message = "Could not get the tree info";
+ }
+
+ return result ? Success : FirstExtensionError;
}
-const char *_XklGetEventName( int type )
+const gchar *
+xkl_event_get_name(gint type)
{
- /* Not really good to use the fact of consecutivity
- but X protocol is already standartized so... */
- static const char *evtNames[] = {
- "KeyPress",
- "KeyRelease",
- "ButtonPress",
- "ButtonRelease",
- "MotionNotify",
- "EnterNotify",
- "LeaveNotify",
- "FocusIn",
- "FocusOut",
- "KeymapNotify",
- "Expose",
- "GraphicsExpose",
- "NoExpose",
- "VisibilityNotify",
- "CreateNotify",
- "DestroyNotify",
- "UnmapNotify",
- "MapNotify",
- "MapRequest",
- "ReparentNotify",
- "ConfigureNotify",
- "ConfigureRequest",
- "GravityNotify",
- "ResizeRequest",
- "CirculateNotify",
- "CirculateRequest",
- "PropertyNotify",
- "SelectionClear",
- "SelectionRequest",
- "SelectionNotify",
- "ColormapNotify", "ClientMessage", "MappingNotify", "LASTEvent"
- };
- type -= KeyPress;
- if( type < 0 ||
- type >= ( sizeof( evtNames ) / sizeof( evtNames[0] ) ) )
- return "UNKNOWN";
- return evtNames[type];
+ /* Not really good to use the fact of consecutivity
+ but X protocol is already standartized so... */
+ static const gchar *evt_names[] = {
+ "KeyPress",
+ "KeyRelease",
+ "ButtonPress",
+ "ButtonRelease",
+ "MotionNotify",
+ "EnterNotify",
+ "LeaveNotify",
+ "FocusIn",
+ "FocusOut",
+ "KeymapNotify",
+ "Expose",
+ "GraphicsExpose",
+ "NoExpose",
+ "VisibilityNotify",
+ "CreateNotify",
+ "DestroyNotify",
+ "UnmapNotify",
+ "MapNotify",
+ "MapRequest",
+ "ReparentNotify",
+ "ConfigureNotify",
+ "ConfigureRequest",
+ "GravityNotify",
+ "ResizeRequest",
+ "CirculateNotify",
+ "CirculateRequest",
+ "PropertyNotify",
+ "SelectionClear",
+ "SelectionRequest",
+ "SelectionNotify",
+ "ColormapNotify", "ClientMessage", "MappingNotify",
+ "LASTEvent"
+ };
+ type -= KeyPress;
+ if (type < 0 || type >= (sizeof(evt_names) / sizeof(evt_names[0])))
+ return "UNKNOWN";
+ return evt_names[type];
}
-void _XklUpdateCurState( int group, unsigned indicators, const char reason[] )
+void
+xkl_engine_update_current_state(XklEngine * engine, int group,
+ unsigned indicators, const char reason[])
{
- XklDebug( 150,
- "Updating the current state with [g:%d/i:%u], reason: %s\n",
- group, indicators, reason );
- _xklCurState.group = group;
- _xklCurState.indicators = indicators;
+ xkl_debug(150,
+ "Updating the current state with [g:%d/i:%u], reason: %s\n",
+ group, indicators, reason);
+ xkl_engine_priv(engine, curr_state).group = group;
+ xkl_engine_priv(engine, curr_state).indicators = indicators;
}
diff --git a/libxklavier/xklavier_xkb.c b/libxklavier/xklavier_xkb.c
index c2b3e60..ebb473a 100644
--- a/libxklavier/xklavier_xkb.c
+++ b/libxklavier/xklavier_xkb.c
@@ -4,31 +4,25 @@
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <X11/Xlibint.h>
#include "xklavier_private.h"
#include "xklavier_private_xkb.h"
#ifdef XKB_HEADERS_PRESENT
-XkbDescPtr _xklXkb;
-static XkbDescPtr precachedXkb = NULL;
-
-char *_xklIndicatorNames[XkbNumIndicators];
-
-int _xklXkbEventType, _xklXkbError;
-
-static char *groupNames[XkbNumKbdGroups];
-
-const char **_XklXkbGetGroupNames( void )
+const gchar **
+xkl_xkb_get_groups_names(XklEngine * engine)
{
- return ( const char ** ) groupNames;
+ return (const gchar **) xkl_engine_backend(engine, XklXkb,
+ group_names);
}
-int _XklXkbPauseListen( void )
+gint
+xkl_xkb_pause_listen(XklEngine * engine)
{
- XkbSelectEvents( _xklDpy, XkbUseCoreKbd, XkbAllEventsMask, 0 );
-/* XkbSelectEventDetails( _xklDpy,
+ XkbSelectEvents(xkl_engine_get_display(engine), XkbUseCoreKbd,
+ XkbAllEventsMask, 0);
+/* XkbSelectEventDetails( xkl_display,
XkbUseCoreKbd,
XkbStateNotify,
0,
@@ -36,12 +30,13 @@ int _XklXkbPauseListen( void )
!!_XklSelectInput( _xklRootWindow, 0 );
*/
- return 0;
+ return 0;
}
-int _XklXkbResumeListen( void )
+gint
+xkl_xkb_resume_listen(XklEngine * engine)
{
- /* What events we want */
+ /* What events we want */
#define XKB_EVT_MASK \
(XkbStateNotifyMask| \
XkbNamesNotifyMask| \
@@ -50,35 +45,43 @@ int _XklXkbResumeListen( void )
XkbIndicatorMapNotifyMask| \
XkbNewKeyboardNotifyMask)
- XkbSelectEvents( _xklDpy, XkbUseCoreKbd, XKB_EVT_MASK, XKB_EVT_MASK );
+ Display *display = xkl_engine_get_display(engine);
+ XkbSelectEvents(display, XkbUseCoreKbd, XKB_EVT_MASK,
+ XKB_EVT_MASK);
#define XKB_STATE_EVT_DTL_MASK \
(XkbGroupStateMask)
- XkbSelectEventDetails( _xklDpy,
- XkbUseCoreKbd,
- XkbStateNotify,
- XKB_STATE_EVT_DTL_MASK, XKB_STATE_EVT_DTL_MASK );
+ XkbSelectEventDetails(display,
+ XkbUseCoreKbd,
+ XkbStateNotify,
+ XKB_STATE_EVT_DTL_MASK,
+ XKB_STATE_EVT_DTL_MASK);
#define XKB_NAMES_EVT_DTL_MASK \
(XkbGroupNamesMask|XkbIndicatorNamesMask)
- XkbSelectEventDetails( _xklDpy,
- XkbUseCoreKbd,
- XkbNamesNotify,
- XKB_NAMES_EVT_DTL_MASK, XKB_NAMES_EVT_DTL_MASK );
- return 0;
+ XkbSelectEventDetails(display,
+ XkbUseCoreKbd,
+ XkbNamesNotify,
+ XKB_NAMES_EVT_DTL_MASK,
+ XKB_NAMES_EVT_DTL_MASK);
+ return 0;
}
-unsigned _XklXkbGetMaxNumGroups( void )
+guint
+xkl_xkb_get_max_num_groups(XklEngine * engine)
{
- return xklVTable->features & XKLF_MULTIPLE_LAYOUTS_SUPPORTED ?
- XkbNumKbdGroups : 1;
+ return xkl_engine_priv(engine,
+ features) & XKLF_MULTIPLE_LAYOUTS_SUPPORTED
+ ? XkbNumKbdGroups : 1;
}
-unsigned _XklXkbGetNumGroups( void )
+guint
+xkl_xkb_get_num_groups(XklEngine * engine)
{
- return _xklXkb->ctrls->num_groups;
+ return xkl_engine_backend(engine, XklXkb,
+ cached_desc)->ctrls->num_groups;
}
#define KBD_MASK \
@@ -88,448 +91,511 @@ unsigned _XklXkbGetNumGroups( void )
#define NAMES_MASK \
( XkbGroupNamesMask | XkbIndicatorNamesMask )
-void _XklXkbFreeAllInfo( void )
+void
+xkl_xkb_free_all_info(XklEngine * engine)
{
- int i;
- char **pi = _xklIndicatorNames;
- for( i = 0; i < XkbNumIndicators; i++, pi++ )
- {
- /* only free non-empty ones */
- if( *pi && **pi )
- XFree( *pi );
- }
- if( _xklXkb != NULL )
- {
- int i;
- char **groupName = groupNames;
- for( i = _xklXkb->ctrls->num_groups; --i >= 0; groupName++ )
- if( *groupName )
- {
- XFree( *groupName );
- *groupName = NULL;
- }
- XkbFreeKeyboard( _xklXkb, XkbAllComponentsMask, True );
- _xklXkb = NULL;
- }
-
- /* just in case - never actually happens...*/
- if( precachedXkb != NULL )
- {
- XkbFreeKeyboard( precachedXkb, XkbAllComponentsMask, True );
- precachedXkb = NULL;
- }
+ gint i;
+ gchar **pi = xkl_engine_backend(engine, XklXkb, indicator_names);
+ for (i = 0; i < XkbNumIndicators; i++, pi++) {
+ /* only free non-empty ones */
+ if (*pi && **pi)
+ XFree(*pi);
+ }
+ XkbDescPtr desc = xkl_engine_backend(engine, XklXkb, cached_desc);
+ if (desc != NULL) {
+ int i;
+ char **group_name =
+ xkl_engine_backend(engine, XklXkb, group_names);
+ for (i = desc->ctrls->num_groups; --i >= 0; group_name++)
+ if (*group_name) {
+ XFree(*group_name);
+ *group_name = NULL;
+ }
+ XkbFreeKeyboard(desc, XkbAllComponentsMask, True);
+ xkl_engine_backend(engine, XklXkb, cached_desc) = NULL;
+ }
+
+ /* just in case - never actually happens... */
+ desc = xkl_engine_backend(engine, XklXkb, actual_desc);
+ if (desc != NULL) {
+ XkbFreeKeyboard(desc, XkbAllComponentsMask, True);
+ xkl_engine_backend(engine, XklXkb, actual_desc) = NULL;
+ }
}
-static Bool _XklXkbLoadPrecachedXkb( void )
+static gboolean
+xkl_xkb_load_actual_desc(XklEngine * engine)
{
- Bool rv = False;
- Status status;
-
- precachedXkb = XkbGetMap( _xklDpy, KBD_MASK, XkbUseCoreKbd );
- if( precachedXkb != NULL )
- {
- rv = Success == ( status = XkbGetControls( _xklDpy, CTRLS_MASK, precachedXkb ) ) &&
- Success == ( status = XkbGetNames( _xklDpy, NAMES_MASK, precachedXkb ) ) &&
- Success == ( status = XkbGetIndicatorMap( _xklDpy, XkbAllIndicatorsMask, precachedXkb ) );
- if( !rv )
- {
- _xklLastErrorMsg = "Could not load controls/names/indicators";
- XklDebug( 0, "%s: %d\n", _xklLastErrorMsg, status );
- XkbFreeKeyboard( precachedXkb, XkbAllComponentsMask, True );
-
- }
- }
- return rv;
+ gboolean rv = FALSE;
+ Status status;
+
+ Display *display = xkl_engine_get_display(engine);
+ XkbDescPtr desc = XkbGetMap(display, KBD_MASK, XkbUseCoreKbd);
+ xkl_engine_backend(engine, XklXkb, actual_desc) = desc;
+ if (desc != NULL) {
+ rv = Success == (status = XkbGetControls(display,
+ CTRLS_MASK,
+ desc)) &&
+ Success == (status = XkbGetNames(display,
+ NAMES_MASK,
+ desc)) &&
+ Success == (status = XkbGetIndicatorMap(display,
+ XkbAllIndicatorsMask,
+ desc));
+ if (!rv) {
+ xkl_last_error_message =
+ "Could not load controls/names/indicators";
+ xkl_debug(0, "%s: %d\n",
+ xkl_last_error_message, status);
+ XkbFreeKeyboard(desc, XkbAllComponentsMask, True);
+ xkl_engine_backend(engine, XklXkb, actual_desc) =
+ NULL;
+ }
+ }
+ return rv;
}
-Bool _XklXkbIfCachedInfoEqualsActual( void )
+gboolean
+xkl_xkb_if_cached_info_equals_actual(XklEngine * engine)
{
- int i;
- Atom *pa1, *pa2;
- Bool rv = False;
-
- if( _XklXkbLoadPrecachedXkb() )
- {
- /* First, compare the number of groups */
- if( _xklXkb->ctrls->num_groups == precachedXkb->ctrls->num_groups )
- {
- /* Then, compare group names, just atoms */
- pa1 = _xklXkb->names->groups;
- pa2 = precachedXkb->names->groups;
- for( i = _xklXkb->ctrls->num_groups; --i >= 0; pa1++, pa2++ )
- if( *pa1 != *pa2 )
- break;
-
- /* Then, compare indicator names, just atoms */
- if( i < 0 )
- {
- pa1 = _xklXkb->names->indicators;
- pa2 = precachedXkb->names->indicators;
- for( i = XkbNumIndicators; --i >= 0; pa1++, pa2++ )
- if( *pa1 != *pa2 )
- break;
- rv = i < 0;
- }
- }
- /**
+ gint i;
+ Atom *pa1, *pa2;
+ gboolean rv = FALSE;
+
+ if (xkl_xkb_load_actual_desc(engine)) {
+ /* First, compare the number of groups */
+ XkbDescPtr cached =
+ xkl_engine_backend(engine, XklXkb, cached_desc);
+ XkbDescPtr actual =
+ xkl_engine_backend(engine, XklXkb, actual_desc);
+
+ if (cached->ctrls->num_groups == actual->ctrls->num_groups) {
+ /* Then, compare group names, just atoms */
+ pa1 = cached->names->groups;
+ pa2 = actual->names->groups;
+ for (i = cached->ctrls->num_groups; --i >= 0;
+ pa1++, pa2++)
+ if (*pa1 != *pa2)
+ break;
+
+ /* Then, compare indicator names, just atoms */
+ if (i < 0) {
+ pa1 = cached->names->indicators;
+ pa2 = actual->names->indicators;
+ for (i = XkbNumIndicators; --i >= 0;
+ pa1++, pa2++)
+ if (*pa1 != *pa2)
+ break;
+ rv = i < 0;
+ }
+ }
+ /*
* in case of failure, reuse in _XklXkbLoadAllInfo
* in case of success - free it
*/
- if( rv )
- {
- XkbFreeKeyboard( precachedXkb, XkbAllComponentsMask, True );
- precachedXkb = NULL;
- }
- } else
- {
- XklDebug( 0, "Could not load the XkbDescPtr for comparison\n" );
- }
- return rv;
+ if (rv) {
+ XkbFreeKeyboard(actual,
+ XkbAllComponentsMask, True);
+ xkl_engine_backend(engine, XklXkb, actual_desc) =
+ NULL;
+ }
+ } else {
+ xkl_debug(0,
+ "Could not load the XkbDescPtr for comparison\n");
+ }
+ return rv;
}
-/**
+/*
* Load some XKB parameters
*/
-Bool _XklXkbLoadAllInfo( void )
+gboolean
+xkl_xkb_load_all_info(XklEngine * engine)
{
- int i;
- Atom *pa;
- char **groupName;
- char **pi = _xklIndicatorNames;
-
- if ( precachedXkb == NULL )
- if ( !_XklXkbLoadPrecachedXkb() )
- {
- _xklLastErrorMsg = "Could not load keyboard";
- return False;
- }
-
- /* take it from the cache (in most cases LoadAll is called from ResetAll which in turn ...)*/
- _xklXkb = precachedXkb;
- precachedXkb = NULL;
-
- /* First, output the number of the groups */
- XklDebug( 200, "found %d groups\n", _xklXkb->ctrls->num_groups );
-
- /* Then, cache (and output) the names of the groups */
- pa = _xklXkb->names->groups;
- groupName = groupNames;
- for( i = _xklXkb->ctrls->num_groups; --i >= 0; pa++, groupName++ )
- {
- *groupName = XGetAtomName( _xklDpy,
- *pa == None ?
- XInternAtom( _xklDpy, "-", False ) : *pa );
- XklDebug( 200, "group %d has name [%s]\n", i, *groupName );
- }
-
- _xklLastErrorCode =
- XkbGetIndicatorMap( _xklDpy, XkbAllIndicatorsMask, _xklXkb );
-
- if( _xklLastErrorCode != Success )
- {
- _xklLastErrorMsg = "Could not load indicator map";
- return False;
- }
-
- /* Then, cache (and output) the names of the indicators */
- pa = _xklXkb->names->indicators;
- for( i = XkbNumIndicators; --i >= 0; pi++, pa++ )
- {
- Atom a = *pa;
- if( a != None )
- *pi = XGetAtomName( _xklDpy, a );
- else
- *pi = "";
-
- XklDebug( 200, "Indicator[%d] is %s\n", i, *pi );
- }
-
- XklDebug( 200, "Real indicators are %X\n",
- _xklXkb->indicators->phys_indicators );
-
- if( _xklConfigCallback != NULL )
- ( *_xklConfigCallback ) ( _xklConfigCallbackData );
- return True;
+ gint i;
+ Atom *pa;
+ gchar **group_name;
+ gchar **pi = xkl_engine_backend(engine, XklXkb, indicator_names);
+ Display *display = xkl_engine_get_display(engine);
+ XkbDescPtr actual =
+ xkl_engine_backend(engine, XklXkb, actual_desc);
+
+ if (actual == NULL)
+ if (!xkl_xkb_load_actual_desc(engine)) {
+ xkl_last_error_message = "Could not load keyboard";
+ return FALSE;
+ }
+
+ /* take it from the cache (in most cases LoadAll is called from ResetAll which in turn ...) */
+ XkbDescPtr cached = actual =
+ xkl_engine_backend(engine, XklXkb, actual_desc);
+ xkl_engine_backend(engine, XklXkb, cached_desc) =
+ xkl_engine_backend(engine, XklXkb, actual_desc);
+ xkl_engine_backend(engine, XklXkb, actual_desc) = NULL;
+
+ /* First, output the number of the groups */
+ xkl_debug(200, "found %d groups\n", cached->ctrls->num_groups);
+
+ /* Then, cache (and output) the names of the groups */
+ pa = cached->names->groups;
+ group_name = xkl_engine_backend(engine, XklXkb, group_names);
+ for (i = cached->ctrls->num_groups; --i >= 0; pa++, group_name++) {
+ *group_name =
+ XGetAtomName(display,
+ *pa == None ? XInternAtom(display,
+ "-",
+ False) : *pa);
+ xkl_debug(200, "Group %d has name [%s]\n", i, *group_name);
+ }
+
+ xkl_engine_priv(engine, last_error_code) =
+ XkbGetIndicatorMap(display, XkbAllIndicatorsMask, cached);
+
+ if (xkl_engine_priv(engine, last_error_code) != Success) {
+ xkl_last_error_message = "Could not load indicator map";
+ return FALSE;
+ }
+
+ /* Then, cache (and output) the names of the indicators */
+ pa = cached->names->indicators;
+ for (i = XkbNumIndicators; --i >= 0; pi++, pa++) {
+ Atom a = *pa;
+ if (a != None)
+ *pi = XGetAtomName(display, a);
+ else
+ *pi = "";
+
+ xkl_debug(200, "Indicator[%d] is %s\n", i, *pi);
+ }
+
+ xkl_debug(200, "Real indicators are %X\n",
+ cached->indicators->phys_indicators);
+
+ g_signal_emit_by_name(engine, "X-config-changed");
+
+ return TRUE;
}
-void _XklXkbLockGroup( int group )
+void
+xkl_xkb_lock_group(XklEngine * engine, gint group)
{
- XklDebug( 100, "Posted request for change the group to %d ##\n", group );
- XkbLockGroup( _xklDpy, XkbUseCoreKbd, group );
- XSync( _xklDpy, False );
+ Display *display = xkl_engine_get_display(engine);
+ xkl_debug(100, "Posted request for change the group to %d ##\n",
+ group);
+ XkbLockGroup(display, XkbUseCoreKbd, group);
+ XSync(display, False);
}
-/**
+/*
* Updates current internal state from X state
*/
-void _XklXkbGetRealState( XklState * curState_return )
+void
+xkl_xkb_get_server_state(XklEngine * engine, XklState * current_state_out)
{
- XkbStateRec state;
-
- curState_return->group = 0;
- if( Success == XkbGetState( _xklDpy, XkbUseCoreKbd, &state ) )
- curState_return->group = state.locked_group;
-
- if( Success ==
- XkbGetIndicatorState( _xklDpy, XkbUseCoreKbd,
- &curState_return->indicators ) )
- curState_return->indicators &= _xklXkb->indicators->phys_indicators;
- else
- curState_return->indicators = 0;
+ XkbStateRec state;
+ Display *display = xkl_engine_get_display(engine);
+
+ current_state_out->group = 0;
+ if (Success == XkbGetState(display, XkbUseCoreKbd, &state))
+ current_state_out->group = state.locked_group;
+
+ if (Success ==
+ XkbGetIndicatorState(display, XkbUseCoreKbd,
+ &current_state_out->indicators))
+ current_state_out->indicators &=
+ xkl_engine_backend(engine, XklXkb,
+ cached_desc)->indicators->
+ phys_indicators;
+ else
+ current_state_out->indicators = 0;
}
/*
* Actually taken from mxkbledpanel, valueChangedProc
*/
-Bool _XklSetIndicator( int indicatorNum, Bool set )
+gboolean
+xkl_xkb_set_indicator(XklEngine * engine, gint indicator_num, gboolean set)
{
- XkbIndicatorMapPtr map;
-
- map = _xklXkb->indicators->maps + indicatorNum;
-
- /* The 'flags' field tells whether this indicator is automatic
- * (XkbIM_NoExplicit - 0x80), explicit (XkbIM_NoAutomatic - 0x40),
- * or neither (both - 0xC0).
- *
- * If NoAutomatic is set, the server ignores the rest of the
- * fields in the indicator map (i.e. it disables automatic control
- * of the LED). If NoExplicit is set, the server prevents clients
- * from explicitly changing the value of the LED (using the core
- * protocol *or* XKB). If NoAutomatic *and* NoExplicit are set,
- * the LED cannot be changed (unless you change the map first).
- * If neither NoAutomatic nor NoExplicit are set, the server will
- * change the LED according to the indicator map, but clients can
- * override that (until the next automatic change) using the core
- * protocol or XKB.
- */
- switch ( map->flags & ( XkbIM_NoExplicit | XkbIM_NoAutomatic ) )
- {
- case XkbIM_NoExplicit | XkbIM_NoAutomatic:
- {
- /* Can do nothing. Just ignore the indicator */
- return True;
- }
-
- case XkbIM_NoAutomatic:
- {
- if( _xklXkb->names->indicators[indicatorNum] != None )
- XkbSetNamedIndicator( _xklDpy, XkbUseCoreKbd,
- _xklXkb->names->indicators[indicatorNum], set,
- False, NULL );
- else
- {
- XKeyboardControl xkc;
- xkc.led = indicatorNum;
- xkc.led_mode = set ? LedModeOn : LedModeOff;
- XChangeKeyboardControl( _xklDpy, KBLed | KBLedMode, &xkc );
- XSync( _xklDpy, 0 );
- }
-
- return True;
- }
-
- case XkbIM_NoExplicit:
- break;
- }
-
- /* The 'ctrls' field tells what controls tell this indicator to
- * to turn on: RepeatKeys (0x1), SlowKeys (0x2), BounceKeys (0x4),
- * StickyKeys (0x8), MouseKeys (0x10), AccessXKeys (0x20),
- * TimeOut (0x40), Feedback (0x80), ToggleKeys (0x100),
- * Overlay1 (0x200), Overlay2 (0x400), GroupsWrap (0x800),
- * InternalMods (0x1000), IgnoreLockMods (0x2000),
- * PerKeyRepeat (0x3000), or ControlsEnabled (0x4000)
- */
- if( map->ctrls )
- {
- unsigned long which = map->ctrls;
-
- XkbGetControls( _xklDpy, XkbAllControlsMask, _xklXkb );
- if( set )
- _xklXkb->ctrls->enabled_ctrls |= which;
- else
- _xklXkb->ctrls->enabled_ctrls &= ~which;
- XkbSetControls( _xklDpy, which | XkbControlsEnabledMask, _xklXkb );
- }
-
- /* The 'which_groups' field tells when this indicator turns on
- * for the 'groups' field: base (0x1), latched (0x2), locked (0x4),
- * or effective (0x8).
- */
- if( map->groups )
- {
- int i;
- unsigned int group = 1;
-
- /* Turning on a group indicator is kind of tricky. For
- * now, we will just Latch or Lock the first group we find
- * if that is what this indicator does. Otherwise, we're
- * just going to punt and get out of here.
- */
- if( set )
- {
- for( i = XkbNumKbdGroups; --i >= 0; )
- if( ( 1 << i ) & map->groups )
- {
- group = i;
- break;
- }
- if( map->which_groups & ( XkbIM_UseLocked | XkbIM_UseEffective ) )
- {
- /* Important: Groups should be ignored here - because they are handled separately! */
- /* XklLockGroup( group ); */
- } else if( map->which_groups & XkbIM_UseLatched )
- XkbLatchGroup( _xklDpy, XkbUseCoreKbd, group );
- else
- {
- /* Can do nothing. Just ignore the indicator */
- return True;
- }
- } else
- /* Turning off a group indicator will mean that we just
- * Lock the first group that this indicator doesn't watch.
- */
- {
- for( i = XkbNumKbdGroups; --i >= 0; )
- if( !( ( 1 << i ) & map->groups ) )
- {
- group = i;
- break;
- }
- XklLockGroup( group );
- }
- }
-
- /* The 'which_mods' field tells when this indicator turns on
- * for the modifiers: base (0x1), latched (0x2), locked (0x4),
- * or effective (0x8).
- *
- * The 'real_mods' field tells whether this turns on when one of
- * the real X modifiers is set: Shift (0x1), Lock (0x2), Control (0x4),
- * Mod1 (0x8), Mod2 (0x10), Mod3 (0x20), Mod4 (0x40), or Mod5 (0x80).
- *
- * The 'virtual_mods' field tells whether this turns on when one of
- * the virtual modifiers is set.
- *
- * The 'mask' field tells what real X modifiers the virtual_modifiers
- * map to?
- */
- if( map->mods.real_mods || map->mods.mask )
- {
- unsigned int affect, mods;
-
- affect = ( map->mods.real_mods | map->mods.mask );
-
- mods = set ? affect : 0;
-
- if( map->which_mods & ( XkbIM_UseLocked | XkbIM_UseEffective ) )
- XkbLockModifiers( _xklDpy, XkbUseCoreKbd, affect, mods );
- else if( map->which_mods & XkbIM_UseLatched )
- XkbLatchModifiers( _xklDpy, XkbUseCoreKbd, affect, mods );
- else
- {
- return True;
- }
- }
- return True;
+ XkbIndicatorMapPtr map;
+ Display *display = xkl_engine_get_display(engine);
+ XkbDescPtr cached =
+ xkl_engine_backend(engine, XklXkb, cached_desc);
+
+ map = cached->indicators->maps + indicator_num;
+
+ /* The 'flags' field tells whether this indicator is automatic
+ * (XkbIM_NoExplicit - 0x80), explicit (XkbIM_NoAutomatic - 0x40),
+ * or neither (both - 0xC0).
+ *
+ * If NoAutomatic is set, the server ignores the rest of the
+ * fields in the indicator map (i.e. it disables automatic control
+ * of the LED). If NoExplicit is set, the server prevents clients
+ * from explicitly changing the value of the LED (using the core
+ * protocol *or* XKB). If NoAutomatic *and* NoExplicit are set,
+ * the LED cannot be changed (unless you change the map first).
+ * If neither NoAutomatic nor NoExplicit are set, the server will
+ * change the LED according to the indicator map, but clients can
+ * override that (until the next automatic change) using the core
+ * protocol or XKB.
+ */
+ switch (map->flags & (XkbIM_NoExplicit | XkbIM_NoAutomatic)) {
+ case XkbIM_NoExplicit | XkbIM_NoAutomatic:
+ {
+ /* Can do nothing. Just ignore the indicator */
+ return TRUE;
+ }
+
+ case XkbIM_NoAutomatic:
+ {
+ if (cached->names->
+ indicators[indicator_num] != None)
+ XkbSetNamedIndicator(display,
+ XkbUseCoreKbd,
+ cached->names->
+ indicators
+ [indicator_num], set,
+ False, NULL);
+ else {
+ XKeyboardControl xkc;
+ xkc.led = indicator_num;
+ xkc.led_mode =
+ set ? LedModeOn : LedModeOff;
+ XChangeKeyboardControl(display,
+ KBLed | KBLedMode,
+ &xkc);
+ XSync(display, False);
+ }
+
+ return TRUE;
+ }
+
+ case XkbIM_NoExplicit:
+ break;
+ }
+
+ /* The 'ctrls' field tells what controls tell this indicator to
+ * to turn on: RepeatKeys (0x1), SlowKeys (0x2), BounceKeys (0x4),
+ * StickyKeys (0x8), MouseKeys (0x10), AccessXKeys (0x20),
+ * TimeOut (0x40), Feedback (0x80), ToggleKeys (0x100),
+ * Overlay1 (0x200), Overlay2 (0x400), GroupsWrap (0x800),
+ * InternalMods (0x1000), IgnoreLockMods (0x2000),
+ * PerKeyRepeat (0x3000), or ControlsEnabled (0x4000)
+ */
+ if (map->ctrls) {
+ gulong which = map->ctrls;
+
+ XkbGetControls(display, XkbAllControlsMask, cached);
+ if (set)
+ cached->ctrls->enabled_ctrls |= which;
+ else
+ cached->ctrls->enabled_ctrls &= ~which;
+ XkbSetControls(display, which | XkbControlsEnabledMask,
+ cached);
+ }
+
+ /* The 'which_groups' field tells when this indicator turns on
+ * for the 'groups' field: base (0x1), latched (0x2), locked (0x4),
+ * or effective (0x8).
+ */
+ if (map->groups) {
+ gint i;
+ guint group = 1;
+
+ /* Turning on a group indicator is kind of tricky. For
+ * now, we will just Latch or Lock the first group we find
+ * if that is what this indicator does. Otherwise, we're
+ * just going to punt and get out of here.
+ */
+ if (set) {
+ for (i = XkbNumKbdGroups; --i >= 0;)
+ if ((1 << i) & map->groups) {
+ group = i;
+ break;
+ }
+ if (map->
+ which_groups & (XkbIM_UseLocked |
+ XkbIM_UseEffective)) {
+ /* Important: Groups should be ignored here - because they are handled separately! */
+ /* XklLockGroup( group ); */
+ } else if (map->which_groups & XkbIM_UseLatched)
+ XkbLatchGroup(display, XkbUseCoreKbd,
+ group);
+ else {
+ /* Can do nothing. Just ignore the indicator */
+ return TRUE;
+ }
+ } else
+ /* Turning off a group indicator will mean that we just
+ * Lock the first group that this indicator doesn't watch.
+ */
+ {
+ for (i = XkbNumKbdGroups; --i >= 0;)
+ if (!((1 << i) & map->groups)) {
+ group = i;
+ break;
+ }
+ xkl_xkb_lock_group(engine, group);
+ }
+ }
+
+ /* The 'which_mods' field tells when this indicator turns on
+ * for the modifiers: base (0x1), latched (0x2), locked (0x4),
+ * or effective (0x8).
+ *
+ * The 'real_mods' field tells whether this turns on when one of
+ * the real X modifiers is set: Shift (0x1), Lock (0x2), Control (0x4),
+ * Mod1 (0x8), Mod2 (0x10), Mod3 (0x20), Mod4 (0x40), or Mod5 (0x80).
+ *
+ * The 'virtual_mods' field tells whether this turns on when one of
+ * the virtual modifiers is set.
+ *
+ * The 'mask' field tells what real X modifiers the virtual_modifiers
+ * map to?
+ */
+ if (map->mods.real_mods || map->mods.mask) {
+ guint affect, mods;
+
+ affect = (map->mods.real_mods | map->mods.mask);
+
+ mods = set ? affect : 0;
+
+ if (map->
+ which_mods & (XkbIM_UseLocked | XkbIM_UseEffective))
+ XkbLockModifiers(display, XkbUseCoreKbd,
+ affect, mods);
+ else if (map->which_mods & XkbIM_UseLatched)
+ XkbLatchModifiers(display, XkbUseCoreKbd,
+ affect, mods);
+ else {
+ return TRUE;
+ }
+ }
+ return TRUE;
}
#endif
-int _XklXkbInit( void )
+gint
+xkl_xkb_init(XklEngine * engine)
{
+ Display *display = xkl_engine_get_display(engine);
+
#ifdef XKB_HEADERS_PRESENT
- int opcode;
- Bool _xklXkbExtPresent;
- static XklVTable xklXkbVTable =
-{
- "XKB",
- XKLF_CAN_TOGGLE_INDICATORS |
- XKLF_CAN_OUTPUT_CONFIG_AS_ASCII |
- XKLF_CAN_OUTPUT_CONFIG_AS_BINARY,
- _XklXkbConfigActivate,
- _XklXkbConfigInit,
- _XklXkbConfigLoadRegistry,
- _XklXkbConfigWriteFile,
- _XklXkbEventHandler,
- _XklXkbFreeAllInfo,
- _XklXkbGetGroupNames,
- _XklXkbGetMaxNumGroups,
- _XklXkbGetNumGroups,
- _XklXkbGetRealState,
- _XklXkbIfCachedInfoEqualsActual,
- _XklXkbLoadAllInfo,
- _XklXkbLockGroup,
- _XklXkbPauseListen,
- _XklXkbResumeListen,
- _XklXkbSetIndicators,
- };
-
- if( getenv( "XKL_XKB_DISABLE" ) != NULL )
- return -1;
-
- _xklXkbExtPresent = XkbQueryExtension( _xklDpy,
- &opcode, &_xklXkbEventType,
- &_xklXkbError, NULL, NULL );
- if( !_xklXkbExtPresent )
- {
- XSetErrorHandler( ( XErrorHandler ) _xklDefaultErrHandler );
- return -1;
- }
-
- XklDebug( 160,
- "xkbEvenType: %X, xkbError: %X, display: %p, root: " WINID_FORMAT
- "\n", _xklXkbEventType, _xklXkbError, _xklDpy, _xklRootWindow );
-
- xklXkbVTable.baseConfigAtom =
- XInternAtom( _xklDpy, _XKB_RF_NAMES_PROP_ATOM, False );
- xklXkbVTable.backupConfigAtom =
- XInternAtom( _xklDpy, "_XKB_RULES_NAMES_BACKUP", False );
-
- xklXkbVTable.defaultModel = "pc101";
- xklXkbVTable.defaultLayout = "us";
-
- xklVTable = &xklXkbVTable;
-
- /* First, we have to assign xklVTable -
- because this function uses it */
-
- if( _XklXkbConfigMultipleLayoutsSupported() )
- xklXkbVTable.features |= XKLF_MULTIPLE_LAYOUTS_SUPPORTED;
-
- return 0;
+ gint opcode;
+ gboolean xkl_xkb_ext_present;
+
+ xkl_engine_priv(engine, backend_id) = "XKB";
+ xkl_engine_priv(engine, features) = XKLF_CAN_TOGGLE_INDICATORS |
+ XKLF_CAN_OUTPUT_CONFIG_AS_ASCII |
+ XKLF_CAN_OUTPUT_CONFIG_AS_BINARY;
+ xkl_engine_priv(engine, activate_config_rec) =
+ xkl_xkb_activate_config_rec;
+ xkl_engine_priv(engine, init_config_registry) =
+ xkl_xkb_init_config_registry;
+ xkl_engine_priv(engine, load_config_registry) =
+ xkl_xkb_load_config_registry;
+ xkl_engine_priv(engine, write_config_rec_to_file) =
+ xkl_xkb_write_config_rec_to_file;
+ xkl_engine_priv(engine, get_groups_names) =
+ xkl_xkb_get_groups_names;
+ xkl_engine_priv(engine, get_max_num_groups) =
+ xkl_xkb_get_max_num_groups;
+ xkl_engine_priv(engine, get_num_groups) = xkl_xkb_get_num_groups;
+ xkl_engine_priv(engine, lock_group) = xkl_xkb_lock_group;
+ xkl_engine_priv(engine, process_x_event) = xkl_xkb_process_x_event;
+ xkl_engine_priv(engine, free_all_info) = xkl_xkb_free_all_info;
+ xkl_engine_priv(engine, if_cached_info_equals_actual) =
+ xkl_xkb_if_cached_info_equals_actual;
+ xkl_engine_priv(engine, load_all_info) = xkl_xkb_load_all_info;
+ xkl_engine_priv(engine, get_server_state) =
+ xkl_xkb_get_server_state;
+ xkl_engine_priv(engine, pause_listen) = xkl_xkb_pause_listen;
+ xkl_engine_priv(engine, resume_listen) = xkl_xkb_resume_listen;
+ xkl_engine_priv(engine, set_indicators) = xkl_xkb_set_indicators;
+ xkl_engine_priv(engine, finalize) = xkl_xkb_term;
+
+ if (getenv("XKL_XKB_DISABLE") != NULL)
+ return -1;
+
+ xkl_engine_priv(engine, backend) = g_new0(XklXkb, 1);
+
+ xkl_xkb_ext_present = XkbQueryExtension(display,
+ &opcode,
+ &xkl_engine_backend(engine,
+ XklXkb,
+ event_type),
+ &xkl_engine_backend(engine,
+ XklXkb,
+ error_code),
+ NULL, NULL);
+ if (!xkl_xkb_ext_present) {
+ XSetErrorHandler((XErrorHandler)
+ xkl_engine_priv(engine,
+ default_error_handler));
+ return -1;
+ }
+
+ xkl_debug(160,
+ "xkbEvenType: %X, xkbError: %X, display: %p, root: "
+ WINID_FORMAT "\n", xkl_engine_backend(engine, XklXkb,
+ event_type),
+ xkl_engine_backend(engine, XklXkb, error_code), display,
+ xkl_engine_priv(engine, root_window));
+
+ xkl_engine_priv(engine, base_config_atom) =
+ XInternAtom(display, _XKB_RF_NAMES_PROP_ATOM, False);
+ xkl_engine_priv(engine, backup_config_atom) =
+ XInternAtom(display, "_XKB_RULES_NAMES_BACKUP", False);
+
+ xkl_engine_priv(engine, default_model) = "pc101";
+ xkl_engine_priv(engine, default_layout) = "us";
+
+ /* First, we have to assign xkl_vtable -
+ because this function uses it */
+
+ if (xkl_xkb_multiple_layouts_supported(engine))
+ xkl_engine_priv(engine, features) |=
+ XKLF_MULTIPLE_LAYOUTS_SUPPORTED;
+
+ return 0;
#else
- XklDebug( 160,
- "NO XKB LIBS, display: %p, root: " WINID_FORMAT
- "\n", _xklDpy, _xklRootWindow );
- return -1;
+ xkl_debug(160,
+ "NO XKB LIBS, display: %p, root: " WINID_FORMAT
+ "\n", display, xkl_engine_priv(engine, root_window));
+ return -1;
#endif
}
+void
+xkl_xkb_term(XklEngine * engine)
+{
+}
+
#ifdef XKB_HEADERS_PRESENT
-const char *_XklXkbGetXkbEventName( int xkb_type )
+const gchar *
+xkl_xkb_event_get_name(gint xkb_type)
{
- /* Not really good to use the fact of consecutivity
- but XKB protocol extension is already standartized so... */
- static const char *evtNames[] = {
- "XkbNewKeyboardNotify",
- "XkbMapNotify",
- "XkbStateNotify",
- "XkbControlsNotify",
- "XkbIndicatorStateNotify",
- "XkbIndicatorMapNotify",
- "XkbNamesNotify",
- "XkbCompatMapNotify",
- "XkbBellNotify",
- "XkbActionMessage",
- "XkbAccessXNotify",
- "XkbExtensionDeviceNotify",
- "LASTEvent"
- };
- xkb_type -= XkbNewKeyboardNotify;
- if( xkb_type < 0 ||
- xkb_type >= ( sizeof( evtNames ) / sizeof( evtNames[0] ) ) )
- return "UNKNOWN";
- return evtNames[xkb_type];
+ /* Not really good to use the fact of consecutivity
+ but XKB protocol extension is already standartized so... */
+ static const gchar *evt_names[] = {
+ "XkbNewKeyboardNotify",
+ "XkbMapNotify",
+ "XkbStateNotify",
+ "XkbControlsNotify",
+ "XkbIndicatorStateNotify",
+ "XkbIndicatorMapNotify",
+ "XkbNamesNotify",
+ "XkbCompatMapNotify",
+ "XkbBellNotify",
+ "XkbActionMessage",
+ "XkbAccessXNotify",
+ "XkbExtensionDeviceNotify",
+ "LASTEvent"
+ };
+ xkb_type -= XkbNewKeyboardNotify;
+ if (xkb_type < 0 ||
+ xkb_type >= (sizeof(evt_names) / sizeof(evt_names[0])))
+ return "UNKNOWN/OOR";
+ return evt_names[xkb_type];
}
#endif
diff --git a/libxklavier/xklavier_xmm.c b/libxklavier/xklavier_xmm.c
index 83818a1..e37b3d8 100755
--- a/libxklavier/xklavier_xmm.c
+++ b/libxklavier/xklavier_xmm.c
@@ -2,10 +2,10 @@
#include <stdlib.h>
#include <string.h>
+#include <X11/Xmd.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <X11/Xlibint.h>
#include <X11/keysym.h>
#include "config.h"
@@ -15,264 +15,325 @@
#define SHORTCUT_OPTION_PREFIX "grp:"
-char* currentXmmRules = NULL;
+const gchar **
+xkl_xmm_get_groups_names(XklEngine * engine)
+{
+ return (const gchar **) xkl_engine_backend(engine, XklXmm,
+ current_config).layouts;
+}
+
+void
+xkl_xmm_shortcuts_grab(XklEngine * engine)
+{
+ const XmmShortcut *shortcut;
+ const XmmSwitchOption *option =
+ xkl_xmm_shortcut_get_current(engine);
-XklConfigRec currentXmmConfig;
+ xkl_debug(150, "Found shortcut option: %p\n", option);
+ if (option == NULL)
+ return;
-Atom xmmStateAtom;
+ shortcut = option->shortcuts;
+ while (shortcut->keysym != XK_VoidSymbol) {
+ int keycode =
+ XKeysymToKeycode(xkl_engine_get_display(engine),
+ shortcut->keysym);
+ xkl_xmm_grab_ignoring_indicators(engine, keycode,
+ shortcut->modifiers);
+ shortcut++;
+ }
+}
-const char **_XklXmmGetGroupNames( void )
+void
+xkl_xmm_shortcuts_ungrab(XklEngine * engine)
{
- return (const char **)currentXmmConfig.layouts;
+ const XmmShortcut *shortcut;
+ const XmmSwitchOption *option =
+ xkl_xmm_shortcut_get_current(engine);
+
+ if (option == NULL)
+ return;
+
+ shortcut = option->shortcuts;
+ while (shortcut->keysym != XK_VoidSymbol) {
+ int keycode =
+ XKeysymToKeycode(xkl_engine_get_display(engine),
+ shortcut->keysym);
+ xkl_xmm_ungrab_ignoring_indicators(engine, keycode,
+ shortcut->modifiers);
+ shortcut++;
+ }
}
-void _XklXmmGrabShortcuts( void )
+XmmSwitchOption *
+xkl_xmm_shortcut_get_current(XklEngine * engine)
{
- int i;
- XmmShortcutPtr shortcut;
- const XmmSwitchOptionPtr option = _XklXmmGetCurrentShortcut();
-
- XklDebug( 150, "Found shortcut option: %p\n", option );
- if( option == NULL )
- return;
-
- shortcut = option->shortcuts;
- for( i = option->numShortcuts; --i >= 0; shortcut++ )
- {
- int keycode = XKeysymToKeycode( _xklDpy, shortcut->keysym );
- _XklXmmGrabIgnoringIndicators( keycode,
- shortcut->modifiers );
- }
+ const gchar *option_name =
+ xkl_xmm_shortcut_get_current_option_name(engine);
+
+ xkl_debug(150, "Configured switch option: [%s]\n", option_name);
+
+ if (option_name == NULL)
+ return NULL;
+
+ return (XmmSwitchOption *)
+ g_hash_table_lookup(xkl_engine_backend
+ (engine, XklXmm, switch_options),
+ (gconstpointer) option_name);
}
-void _XklXmmUngrabShortcuts( void )
+const gchar *
+xkl_xmm_shortcut_get_current_option_name(XklEngine * engine)
{
- int i;
- XmmShortcutPtr shortcut;
- const XmmSwitchOptionPtr option = _XklXmmGetCurrentShortcut();
-
- if( option == NULL )
- return;
-
- shortcut = option->shortcuts;
- for( i = option->numShortcuts; --i >= 0; shortcut++ )
- {
- int keycode = XKeysymToKeycode( _xklDpy, shortcut->keysym );
- _XklXmmUngrabIgnoringIndicators( keycode,
- shortcut->modifiers );
- }
+ gchar **option =
+ xkl_engine_backend(engine, XklXmm, current_config).options;
+ if (option == NULL)
+ return NULL;
+
+ while (*option != NULL) {
+ /* starts with "grp:" */
+ if (strstr(*option, SHORTCUT_OPTION_PREFIX) != NULL) {
+ return *option + sizeof SHORTCUT_OPTION_PREFIX - 1;
+ }
+ option++;
+ }
+ return NULL;
}
-XmmSwitchOptionPtr _XklXmmGetCurrentShortcut( void )
+const XmmSwitchOption *
+xkl_xmm_find_switch_option(XklEngine * engine, gint keycode,
+ guint state, gint * current_shortcut_rv)
{
- const char* optionName = _XklXmmGetCurrentShortcutOptionName();
- XmmSwitchOptionPtr switchOption = allSwitchOptions;
- XklDebug( 150, "Configured switch option: [%s]\n", optionName );
- if( optionName == NULL )
- return NULL;
- while( switchOption->optionName != NULL )
- {
- if( !strcmp( switchOption->optionName, optionName ) )
- return switchOption;
- switchOption++;
- }
- return NULL;
+ const XmmSwitchOption *rv = xkl_xmm_shortcut_get_current(engine);
+
+ if (rv != NULL) {
+ XmmShortcut *sc = rv->shortcuts;
+ while (sc->keysym != XK_VoidSymbol) {
+ if ((XKeysymToKeycode
+ (xkl_engine_get_display(engine),
+ sc->keysym) == keycode)
+ && ((state & sc->modifiers) == sc->modifiers)) {
+ return rv;
+ }
+ sc++;
+ }
+ }
+ return NULL;
}
-const char* _XklXmmGetCurrentShortcutOptionName( void )
+gint
+xkl_xmm_resume_listen(XklEngine * engine)
{
- int i;
- char** option = currentXmmConfig.options;
- for( i = currentXmmConfig.numOptions; --i >= 0; option++ )
- {
- /* starts with "grp:" */
- if( strstr( *option, SHORTCUT_OPTION_PREFIX ) != NULL )
- {
- return *option + sizeof SHORTCUT_OPTION_PREFIX - 1;
- }
- }
- return NULL;
+ if (xkl_engine_priv(engine, listener_type) & XKLL_MANAGE_LAYOUTS)
+ xkl_xmm_shortcuts_grab(engine);
+ return 0;
}
-XmmSwitchOptionPtr _XklXmmFindSwitchOption( unsigned keycode,
- unsigned state,
- int* currentShortcut_rv )
+gint
+xkl_xmm_pause_listen(XklEngine * engine)
{
- const XmmSwitchOptionPtr rv = _XklXmmGetCurrentShortcut();
- int i;
-
- if( rv != NULL )
- {
- XmmShortcutPtr sc = rv->shortcuts;
- for( i=rv->numShortcuts; --i>=0; sc++ )
- {
- if( ( XKeysymToKeycode( _xklDpy, sc->keysym ) == keycode ) &&
- ( ( state & sc->modifiers ) == sc->modifiers ) )
- {
- return rv;
- }
- }
- }
- return NULL;
+ if (xkl_engine_priv(engine, listener_type) & XKLL_MANAGE_LAYOUTS)
+ xkl_xmm_shortcuts_ungrab(engine);
+ return 0;
}
-int _XklXmmResumeListen( void )
+guint
+xkl_xmm_get_max_num_groups(XklEngine * engine)
{
- if( _xklListenerType & XKLL_MANAGE_LAYOUTS )
- _XklXmmGrabShortcuts();
- return 0;
+ return 0;
}
-int _XklXmmPauseListen( void )
+guint
+xkl_xmm_get_num_groups(XklEngine * engine)
{
- if( _xklListenerType & XKLL_MANAGE_LAYOUTS )
- _XklXmmUngrabShortcuts();
- return 0;
+ gint rv = 0;
+ gchar **p =
+ xkl_engine_backend(engine, XklXmm, current_config).layouts;
+ if (p != NULL)
+ while (*p++ != NULL)
+ rv++;
+ return rv;
}
-unsigned _XklXmmGetMaxNumGroups( void )
+void
+xkl_xmm_free_all_info(XklEngine * engine)
{
- return 0;
+ gchar *current_rules =
+ xkl_engine_backend(engine, XklXmm, current_rules);
+ if (current_rules != NULL) {
+ g_free(current_rules);
+ current_rules = NULL;
+ xkl_engine_backend(engine, XklXmm, current_rules) = NULL;
+ }
+ xkl_config_rec_reset(&xkl_engine_backend
+ (engine, XklXmm, current_config));
}
-unsigned _XklXmmGetNumGroups( void )
+gboolean
+xkl_xmm_if_cached_info_equals_actual(XklEngine * engine)
{
- return currentXmmConfig.numLayouts;
+ return FALSE;
}
-
-void _XklXmmFreeAllInfo( void )
+
+gboolean
+xkl_xmm_load_all_info(XklEngine * engine)
{
- if( currentXmmRules != NULL )
- {
- free( currentXmmRules );
- currentXmmRules = NULL;
- }
- XklConfigRecReset( &currentXmmConfig );
+ return
+ xkl_config_rec_get_full_from_server(&xkl_engine_backend
+ (engine, XklXmm,
+ current_rules),
+ &xkl_engine_backend(engine,
+ XklXmm,
+ current_config),
+ engine);
}
-Bool _XklXmmIfCachedInfoEqualsActual( void )
+void
+xkl_xmm_get_server_state(XklEngine * engine, XklState * state)
{
- return False;
+ unsigned char *propval = NULL;
+ Atom actual_type;
+ int actual_format;
+ unsigned long bytes_remaining;
+ unsigned long actual_items;
+ int result;
+
+ memset(state, 0, sizeof(*state));
+
+ result =
+ XGetWindowProperty(xkl_engine_get_display(engine),
+ xkl_engine_priv(engine, root_window),
+ xkl_engine_backend(engine, XklXmm,
+ state_atom), 0L, 1L,
+ False, XA_INTEGER, &actual_type,
+ &actual_format, &actual_items,
+ &bytes_remaining, &propval);
+
+ if (Success == result) {
+ if (actual_format == 32 || actual_items == 1) {
+ state->group = *(CARD32 *) propval;
+ } else {
+ xkl_debug(160,
+ "Could not get the xmodmap current group\n");
+ }
+ XFree(propval);
+ } else {
+ xkl_debug(160,
+ "Could not get the xmodmap current group: %d\n",
+ result);
+ }
}
-Bool _XklXmmLoadAllInfo( )
+void
+xkl_xmm_actualize_group(XklEngine * engine, gint group)
{
- return _XklConfigGetFullFromServer( &currentXmmRules, &currentXmmConfig );
+ char cmd[1024];
+ int res;
+ const gchar *layout_name = NULL;
+
+ if (xkl_xmm_get_num_groups(engine) < group)
+ return;
+
+ layout_name =
+ xkl_engine_backend(engine, XklXmm,
+ current_config).layouts[group];
+
+ snprintf(cmd, sizeof cmd,
+ "xmodmap %s/xmodmap.%s", XMODMAP_BASE, layout_name);
+
+ res = system(cmd);
+ if (res > 0) {
+ xkl_debug(0, "xmodmap error %d\n", res);
+ } else if (res < 0) {
+ xkl_debug(0, "Could not execute xmodmap: %d\n", res);
+ }
+ XSync(xkl_engine_get_display(engine), False);
}
-void _XklXmmGetRealState( XklState * state )
+void
+xkl_xmm_lock_group(XklEngine * engine, gint group)
{
- unsigned char *propval = NULL;
- Atom actualType;
- int actualFormat;
- unsigned long bytesRemaining;
- unsigned long actualItems;
- int result;
-
- memset( state, 0, sizeof( *state ) );
-
- result = XGetWindowProperty( _xklDpy, _xklRootWindow, xmmStateAtom, 0L, 1L,
- False, XA_INTEGER, &actualType, &actualFormat,
- &actualItems, &bytesRemaining,
- &propval );
-
- if( Success == result )
- {
- if( actualFormat == 32 || actualItems == 1 )
- {
- state->group = *(CARD32*)propval;
- } else
- {
- XklDebug( 160, "Could not get the xmodmap current group\n" );
- }
- XFree( propval );
- } else
- {
- XklDebug( 160, "Could not get the xmodmap current group: %d\n", result );
- }
+ CARD32 propval;
+
+ if (xkl_xmm_get_num_groups(engine) < group)
+ return;
+
+ /* updating the status property */
+ propval = group;
+ Display *display = xkl_engine_get_display(engine);
+ XChangeProperty(display, xkl_engine_priv(engine, root_window),
+ xkl_engine_backend(engine, XklXmm, state_atom),
+ XA_INTEGER, 32, PropModeReplace,
+ (unsigned char *) &propval, 1);
+ XSync(display, False);
}
-void _XklXmmActualizeGroup( int group )
+void
+xkl_xmm_set_indicators(XklEngine * engine, const XklState * window_state)
{
- char cmd[1024];
- int res;
- const char* layoutName = NULL;
-
- if( currentXmmConfig.numLayouts < group )
- return;
-
- layoutName = currentXmmConfig.layouts[group];
-
- snprintf( cmd, sizeof cmd,
- "xmodmap %s/xmodmap.%s",
- XMODMAP_BASE, layoutName );
-
- res = system( cmd );
- if( res > 0 )
- {
- XklDebug( 0, "xmodmap error %d\n", res );
- } else if( res < 0 )
- {
- XklDebug( 0, "Could not execute xmodmap: %d\n", res );
- }
- XSync( _xklDpy, False );
}
-void _XklXmmLockGroup( int group )
+
+gint
+xkl_xmm_init(XklEngine * engine)
{
- CARD32 propval;
-
- if( currentXmmConfig.numLayouts < group )
- return;
-
- /* updating the status property */
- propval = group;
- XChangeProperty( _xklDpy, _xklRootWindow, xmmStateAtom,
- XA_INTEGER, 32, PropModeReplace,
- (unsigned char*)&propval, 1 );
- XSync( _xklDpy, False );
+ xkl_engine_priv(engine, backend_id) = "xmodmap";
+ xkl_engine_priv(engine, features) =
+ XKLF_MULTIPLE_LAYOUTS_SUPPORTED |
+ XKLF_REQUIRES_MANUAL_LAYOUT_MANAGEMENT;
+ xkl_engine_priv(engine, activate_config_rec) =
+ xkl_xmm_activate_config_rec;
+ xkl_engine_priv(engine, init_config_registry) =
+ xkl_xmm_init_config_registry;
+ xkl_engine_priv(engine, load_config_registry) =
+ xkl_xmm_load_config_registry;
+ xkl_engine_priv(engine, write_config_rec_to_file) = NULL;
+
+ xkl_engine_priv(engine, get_groups_names) =
+ xkl_xmm_get_groups_names;
+ xkl_engine_priv(engine, get_max_num_groups) =
+ xkl_xmm_get_max_num_groups;
+ xkl_engine_priv(engine, get_num_groups) = xkl_xmm_get_num_groups;
+ xkl_engine_priv(engine, lock_group) = xkl_xmm_lock_group;
+
+ xkl_engine_priv(engine, process_x_event) = xkl_xmm_process_x_event;
+ xkl_engine_priv(engine, free_all_info) = xkl_xmm_free_all_info;
+ xkl_engine_priv(engine, if_cached_info_equals_actual) =
+ xkl_xmm_if_cached_info_equals_actual;
+ xkl_engine_priv(engine, load_all_info) = xkl_xmm_load_all_info;
+ xkl_engine_priv(engine, get_server_state) =
+ xkl_xmm_get_server_state;
+ xkl_engine_priv(engine, pause_listen) = xkl_xmm_pause_listen;
+ xkl_engine_priv(engine, resume_listen) = xkl_xmm_resume_listen;
+ xkl_engine_priv(engine, set_indicators) = xkl_xmm_set_indicators;
+ xkl_engine_priv(engine, finalize) = xkl_xmm_term;
+
+ if (getenv("XKL_XMODMAP_DISABLE") != NULL)
+ return -1;
+
+ Display *display = xkl_engine_get_display(engine);
+ xkl_engine_priv(engine, base_config_atom) =
+ XInternAtom(display, "_XMM_NAMES", False);
+ xkl_engine_priv(engine, backup_config_atom) =
+ XInternAtom(display, "_XMM_NAMES_BACKUP", False);
+
+ xkl_engine_priv(engine, backend) = g_new0(XklXmm, 1);
+
+ xkl_engine_backend(engine, XklXmm, state_atom) =
+ XInternAtom(display, "_XMM_STATE", False);
+
+ xkl_engine_priv(engine, default_model) = "generic";
+ xkl_engine_priv(engine, default_layout) = "us";
+
+ xkl_xmm_init_switch_options((XklXmm *)
+ xkl_engine_priv(engine, backend));
+
+ return 0;
}
-int _XklXmmInit( void )
+void
+xkl_xmm_term(XklEngine * engine)
{
- static XklVTable xklXmmVTable =
- {
- "xmodmap",
- XKLF_MULTIPLE_LAYOUTS_SUPPORTED |
- XKLF_REQUIRES_MANUAL_LAYOUT_MANAGEMENT,
- _XklXmmConfigActivate,
- _XklXmmConfigInit,
- _XklXmmConfigLoadRegistry,
- NULL,
- _XklXmmEventHandler,
- _XklXmmFreeAllInfo,
- _XklXmmGetGroupNames,
- _XklXmmGetMaxNumGroups,
- _XklXmmGetNumGroups,
- _XklXmmGetRealState,
- _XklXmmIfCachedInfoEqualsActual,
- _XklXmmLoadAllInfo,
- _XklXmmLockGroup,
- _XklXmmPauseListen,
- _XklXmmResumeListen,
- NULL,
- };
-
- if( getenv( "XKL_XMODMAP_DISABLE" ) != NULL )
- return -1;
-
- xklXmmVTable.baseConfigAtom =
- XInternAtom( _xklDpy, "_XMM_NAMES", False );
- xklXmmVTable.backupConfigAtom =
- XInternAtom( _xklDpy, "_XMM_NAMES_BACKUP", False );
-
- xmmStateAtom =
- XInternAtom( _xklDpy, "_XMM_STATE", False );
-
- xklXmmVTable.defaultModel = "generic";
- xklXmmVTable.defaultLayout = "us";
-
- xklVTable = &xklXmmVTable;
-
- return 0;
+ xkl_xmm_term_switch_options((XklXmm *)
+ xkl_engine_priv(engine, backend));
}
diff --git a/libxklavier/xklavier_xmm_opts.c b/libxklavier/xklavier_xmm_opts.c
index d082482..8a02edc 100644
--- a/libxklavier/xklavier_xmm_opts.c
+++ b/libxklavier/xklavier_xmm_opts.c
@@ -5,7 +5,6 @@
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <X11/Xlibint.h>
#include <X11/keysym.h>
#include "config.h"
@@ -15,90 +14,139 @@
#define SHORTCUT_OPTION_PREFIX "grp:"
-XmmSwitchOption allSwitchOptions[] =
-{
- {
- "ralt_toggle", 1,
- { { XK_Alt_R, 0 } }, { 1 }
- },
- {
- "lalt_toggle", 1,
- { { XK_Alt_L, 0 } }, { 1 }
- },
- {
- "caps_toggle", 1,
- { { XK_Caps_Lock, 0 } }, { 1 }
- },
- {
- "shift_caps_toggle", 1,
- { { XK_Caps_Lock, ShiftMask } }, { 1 }
- },
- {
- "shifts_toggle", 2,
- { { XK_Shift_R, ShiftMask },
- { XK_Shift_L, ShiftMask } }, { 1, -1 }
- },
- {
- "alts_toggle", 2,
- { { XK_Alt_R, Mod1Mask },
- { XK_Alt_L, Mod1Mask } }, { 1, -1 }
- },
- {
- "ctrls_toggle", 2,
- { { XK_Control_R, ControlMask },
- { XK_Control_L, ControlMask } }, { 1, -1 }
- },
- {
- "ctrl_shift_toggle", 4,
- { { XK_Control_R, ShiftMask },
- { XK_Control_L, ShiftMask },
- { XK_Shift_R, ControlMask },
- { XK_Shift_L, ControlMask } }, { 1, -1, 1, -1 }
- },
- {
- "ctrl_alt_toggle", 4,
- { { XK_Control_R, Mod1Mask },
- { XK_Control_L, Mod1Mask },
- { XK_Alt_R, ControlMask },
- { XK_Alt_L, ControlMask } }, { 1, -1, 1, -1 }
- },
- {
- "alt_shift_toggle", 4,
- { { XK_Shift_R, Mod1Mask },
- { XK_Shift_L, Mod1Mask },
- { XK_Alt_R, ShiftMask },
- { XK_Alt_L, ShiftMask } }, { 1, -1, 1, -1 }
- },
- {
- "menu_toggle", 1,
- { { XK_Menu, 0 } }, { 1 }
- },
- {
- "lwin_toggle", 1,
- { { XK_Super_L, 0 } }, { 1 }
- },
- {
- "rwin_toggle", 1,
- { { XK_Super_R, 0 } }, { 1 }
- },
- {
- "lshift_toggle", 1,
- { { XK_Shift_L, 0 } }, { 1 }
- },
- {
- "rshift_toggle", 1,
- { { XK_Shift_R, 0 } }, { 1 }
- },
- {
- "lctrl_toggle", 1,
- { { XK_Control_L, 0 } }, { 1 }
- },
- {
- "rctrl_toggle", 1,
- { { XK_Control_R, 0 } }, { 1 }
- },
- {
- NULL, 1,
- { { 0, 0 } }, { 1 }
- }
+static XmmSwitchOption options[] = {
+ {{{XK_Alt_R, 0}
+ , {XK_VoidSymbol}
+ }
+ , {1}},
+ {{{XK_Alt_L, 0}
+ , {XK_VoidSymbol}
+ }
+ , {1}},
+ {{{XK_Caps_Lock, 0}
+ , {XK_VoidSymbol}
+ }
+ , {1}},
+ {{{XK_Caps_Lock, ShiftMask}
+ , {XK_VoidSymbol}
+ }
+ , {1}},
+ {{{XK_Shift_R, ShiftMask}
+ ,
+ {XK_Shift_L, ShiftMask}
+ , {XK_VoidSymbol}
+ }
+ , {1, -1}},
+ {{{XK_Alt_R, Mod1Mask}
+ ,
+ {XK_Alt_L, Mod1Mask}
+ , {XK_VoidSymbol}
+ }
+ , {1, -1}},
+ {{{XK_Control_R, ControlMask}
+ ,
+ {XK_Control_L, ControlMask}
+ , {XK_VoidSymbol}
+ }
+ , {1, -1}},
+ {{{XK_Control_R, ShiftMask}
+ ,
+ {XK_Control_L, ShiftMask}
+ ,
+ {XK_Shift_R, ControlMask}
+ ,
+ {XK_Shift_L, ControlMask}
+ , {XK_VoidSymbol}
+ }
+ , {1, -1, 1, -1}},
+ {{{XK_Control_R, Mod1Mask}
+ ,
+ {XK_Control_L, Mod1Mask}
+ ,
+ {XK_Alt_R, ControlMask}
+ ,
+ {XK_Alt_L, ControlMask}
+ , {XK_VoidSymbol}
+ }
+ , {1, -1, 1, -1}},
+ {{{XK_Shift_R, Mod1Mask}
+ ,
+ {XK_Shift_L, Mod1Mask}
+ ,
+ {XK_Alt_R, ShiftMask}
+ ,
+ {XK_Alt_L, ShiftMask}
+ , {XK_VoidSymbol}
+ }
+ , {1, -1, 1, -1}},
+ {{{XK_Menu, 0}
+ , {XK_VoidSymbol}
+ }
+ , {1}},
+ {{{XK_Super_L, 0}
+ , {XK_VoidSymbol}
+ }
+ , {1}},
+ {{{XK_Super_R, 0}
+ , {XK_VoidSymbol}
+ }
+ , {1}},
+ {{{XK_Shift_L, 0}
+ , {XK_VoidSymbol}
+ }
+ , {1}},
+ {{{XK_Shift_R, 0}
+ , {XK_VoidSymbol}
+ }
+ , {1}},
+ {{{XK_Control_L, 0}
+ , {XK_VoidSymbol}
+ }
+ , {1}},
+ {{{XK_Control_R, 0}
+ , {XK_VoidSymbol}
+ }
+ , {1}}
+};
+
+static const gchar *option_names[] = {
+ "ralt_toggle",
+ "lalt_toggle",
+ "caps_toggle",
+ "shift_caps_toggle",
+ "shifts_toggle",
+ "alts_toggle",
+ "ctrls_toggle",
+ "ctrl_shift_toggle",
+ "ctrl_alt_toggle",
+ "alt_shift_toggle",
+ "menu_toggle",
+ "lwin_toggle",
+ "rwin_toggle",
+ "lshift_toggle",
+ "rshift_toggle",
+ "lctrl_toggle",
+ "rctrl_toggle"
};
+
+void
+xkl_xmm_init_switch_options(XklXmm * xmm)
+{
+ int i;
+ const gchar **pname = option_names;
+ const XmmSwitchOption *poption = options;
+
+ xmm->switch_options = g_hash_table_new(g_str_hash, g_str_equal);
+
+ for (i = sizeof(option_names) / sizeof(option_names[0]); --i >= 0;)
+ g_hash_table_insert(xmm->switch_options,
+ (gpointer) (*pname++),
+ (gpointer) (poption++));
+}
+
+void
+xkl_xmm_term_switch_options(XklXmm * xmm)
+{
+ g_hash_table_destroy(xmm->switch_options);
+ xmm->switch_options = NULL;
+}
diff --git a/tests/.indent.pro b/tests/.indent.pro
new file mode 100644
index 0000000..dbec33f
--- /dev/null
+++ b/tests/.indent.pro
@@ -0,0 +1,3 @@
+-kr
+-i8
+-psl
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 9d844da..3690756 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -4,7 +4,7 @@ test_config_SOURCES=test_config.c
test_monitor_SOURCES=test_monitor.c
-AM_CFLAGS=-Wall -Werror -I$(includedir) -I$(x_includes) -I$(top_srcdir)
+AM_CFLAGS=-Wall -Werror -I$(includedir) -I$(x_includes) -I$(top_srcdir) $(GLIB_CFLAGS)
-AM_LDFLAGS=$(top_builddir)/libxklavier/libxklavier.la -L$(x_libraries) -lX11
+AM_LDFLAGS=$(top_builddir)/libxklavier/libxklavier.la -L$(x_libraries) -lX11 $(GLIB_LIBS)
diff --git a/tests/test_config.c b/tests/test_config.c
index 9cc17be..ea35aa2 100644
--- a/tests/test_config.c
+++ b/tests/test_config.c
@@ -6,217 +6,223 @@
#include <string.h>
#include <X11/Xlib.h>
#include <libxklavier/xklavier.h>
-#include <libxklavier/xklavier_config.h>
#ifdef HAVE_SETLOCALE
# include <locale.h>
#endif
-#ifdef __STRICT_ANSI__
-/* these are functions which are NOT in ANSI C.
- Probably we should provide the implementation */
-extern char *strdup( const char *s );
-#endif
-
-extern void XklConfigDump( FILE* file,
- XklConfigRecPtr data );
+extern void xkl_config_rec_dump(FILE * file, XklConfigRec * data);
enum { ACTION_NONE, ACTION_GET, ACTION_SET, ACTION_WRITE };
-static void printUsage(void)
+static void
+print_usage(void)
{
- printf( "Usage: test_config (-g)|(-s -m <model> -l <layouts> -o <options>)|(-h)|(-ws)|(-wb)(-d <debugLevel>)\n" );
- printf( "Options:\n" );
- printf( " -g - Dump the current config, load original system settings and revert back\n" );
- printf( " -s - Set the configuration given my -m -l -o options. Similar to setxkbmap\n" );
- printf( " -ws - Write the binary XKB config file (" PACKAGE ".xkm)\n" );
- printf( " -wb - Write the source XKB config file (" PACKAGE ".xkb)\n" );
- printf( " -d - Set the debug level (by default, 0)\n" );
- printf( " -h - Show this help\n" );
+ printf
+ ("Usage: test_config (-g)|(-s -m <model> -l <layouts> -o <options>)|(-h)|(-ws)|(-wb)(-d <debugLevel>)\n");
+ printf("Options:\n");
+ printf
+ (" -g - Dump the current config, load original system settings and revert back\n");
+ printf
+ (" -s - Set the configuration given my -m -l -o options. Similar to setxkbmap\n");
+ printf(" -ws - Write the binary XKB config file (" PACKAGE
+ ".xkm)\n");
+ printf(" -wb - Write the source XKB config file (" PACKAGE
+ ".xkb)\n");
+ printf(" -d - Set the debug level (by default, 0)\n");
+ printf(" -h - Show this help\n");
}
-int main( int argc, char * const argv[] )
+int
+main(int argc, char *const argv[])
{
- int c, i;
- int action = ACTION_NONE;
- const char* model = NULL;
- const char* layouts = NULL;
- const char* options = NULL;
- int debugLevel = -1;
- int binary = 0;
- Display *dpy;
-
- while (1)
- {
- c = getopt( argc, argv, "hsgm:l:o:d:w:" );
- if ( c == -1 )
- break;
- switch (c)
- {
- case 's':
- printf( "Set the config\n" );
- action = ACTION_SET;
- break;
- case 'g':
- printf( "Get the config\n" );
- action = ACTION_GET;
- break;
- case 'm':
- printf( "Model: [%s]\n", model = optarg );
- break;
- case 'l':
- printf( "Layouts: [%s]\n", layouts = optarg );
- break;
- case 'o':
- printf( "Options: [%s]\n", options = optarg );
- break;
- case 'h':
- printUsage();
- exit(0);
- case 'd':
- debugLevel = atoi( optarg );
- break;
- case 'w':
- action = ACTION_WRITE;
- binary = ( 'b' == optarg[0] );
- default:
- fprintf( stderr, "?? getopt returned character code 0%o ??\n", c );
- printUsage();
- }
- }
-
- if ( action == ACTION_NONE )
- {
- printUsage();
- exit( 0 );
- }
+ int c;
+ int action = ACTION_NONE;
+ const char *model = NULL;
+ const char *layouts = NULL;
+ const char *options = NULL;
+ int debug_level = -1;
+ int binary = 0;
+ Display *dpy;
+
+ g_type_init_with_debug_flags(G_TYPE_DEBUG_OBJECTS |
+ G_TYPE_DEBUG_SIGNALS);
+
+ while (1) {
+ c = getopt(argc, argv, "hsgm:l:o:d:w:");
+ if (c == -1)
+ break;
+ switch (c) {
+ case 's':
+ printf("Set the config\n");
+ action = ACTION_SET;
+ break;
+ case 'g':
+ printf("Get the config\n");
+ action = ACTION_GET;
+ break;
+ case 'm':
+ printf("Model: [%s]\n", model = optarg);
+ break;
+ case 'l':
+ printf("Layouts: [%s]\n", layouts = optarg);
+ break;
+ case 'o':
+ printf("Options: [%s]\n", options = optarg);
+ break;
+ case 'h':
+ print_usage();
+ exit(0);
+ case 'd':
+ debug_level = atoi(optarg);
+ break;
+ case 'w':
+ action = ACTION_WRITE;
+ binary = ('b' == optarg[0]);
+ default:
+ fprintf(stderr,
+ "?? getopt returned character code 0%o ??\n",
+ c);
+ print_usage();
+ }
+ }
+
+ if (action == ACTION_NONE) {
+ print_usage();
+ exit(0);
+ }
#ifdef HAVE_SETLOCALE
- setlocale( LC_ALL, "" );
+ setlocale( LC_ALL, "" );
#endif
- dpy = XOpenDisplay( NULL );
- if ( dpy == NULL )
- {
- fprintf( stderr, "Could not open display\n" );
- exit(1);
- }
- printf( "opened display: %p\n", dpy );
- if ( !XklInit( dpy ) )
- {
- XklConfigRec currentConfig, r2;
- if( debugLevel != -1 )
- XklSetDebugLevel( debugLevel );
- XklDebug( 0, "Xklavier initialized\n" );
- XklConfigInit();
- XklConfigLoadRegistry();
- XklDebug( 0, "Xklavier registry loaded\n" );
- XklDebug( 0, "Backend: [%s]\n", XklGetBackendName() );
- XklDebug( 0, "Supported features: 0x0%X\n", XklGetBackendFeatures() );
- XklDebug( 0, "Max number of groups: %d\n", XklGetMaxNumGroups() );
-
- XklConfigRecInit( &currentConfig );
- XklConfigGetFromServer( &currentConfig );
-
- switch ( action )
- {
- case ACTION_GET:
- XklDebug( 0, "Got config from the server\n" );
- XklConfigDump( stdout, &currentConfig );
-
- XklConfigRecInit( &r2 );
-
- if ( XklConfigGetFromBackup( &r2 ) )
- {
- XklDebug( 0, "Got config from the backup\n" );
- XklConfigDump( stdout, &r2 );
- }
-
- if ( XklConfigActivate( &r2 ) )
- {
- XklDebug( 0, "The backup configuration restored\n" );
- if ( XklConfigActivate( &currentConfig ) )
- {
- XklDebug( 0, "Reverting the configuration change\n" );
- } else
- {
- XklDebug( 0, "The configuration could not be reverted: %s\n", XklGetLastError() );
- }
- } else
- {
- XklDebug( 0, "The backup configuration could not be restored: %s\n", XklGetLastError() );
- }
-
- XklConfigRecDestroy( &r2 );
- break;
- case ACTION_SET:
- if ( model != NULL )
- {
- if ( currentConfig.model != NULL ) free ( currentConfig.model );
- currentConfig.model = strdup( model );
- }
-
- if ( layouts != NULL )
- {
- if ( currentConfig.layouts != NULL )
- {
- for ( i = currentConfig.numLayouts; --i >=0; )
- free ( currentConfig.layouts[i] );
- free ( currentConfig.layouts );
- for ( i = currentConfig.numVariants; --i >=0; )
- free ( currentConfig.variants[i] );
- free ( currentConfig.variants );
- }
- currentConfig.numLayouts =
- currentConfig.numVariants = 1;
- currentConfig.layouts = malloc( sizeof ( char* ) );
- currentConfig.layouts[0] = strdup( layouts );
- currentConfig.variants = malloc( sizeof ( char* ) );
- currentConfig.variants[0] = strdup( "" );
- }
-
- if ( options != NULL )
- {
- if ( currentConfig.options != NULL )
- {
- for ( i = currentConfig.numOptions; --i >=0; )
- free ( currentConfig.options[i] );
- free ( currentConfig.options );
- }
- currentConfig.numOptions = 1;
- currentConfig.options = malloc( sizeof ( char* ) );
- currentConfig.options[0] = strdup( options );
- }
-
- XklDebug( 0, "New config:\n" );
- XklConfigDump( stdout, &currentConfig );
- if ( XklConfigActivate( &currentConfig ) )
- XklDebug( 0, "Set the config\n" );
- else
- XklDebug( 0, "Could not set the config: %s\n", XklGetLastError() );
- break;
- case ACTION_WRITE:
- XklConfigWriteFile( binary ? ( PACKAGE ".xkm" ) : ( PACKAGE ".xkb" ),
- &currentConfig,
- binary );
- XklDebug( 0, "The file " PACKAGE "%s is written\n",
- binary ? ".xkm" : ".xkb" );
- break;
- }
-
- XklConfigRecDestroy( &currentConfig );
-
- XklConfigFreeRegistry();
- XklConfigTerm();
- XklDebug( 0, "Xklavier registry freed\n" );
- XklDebug( 0, "Xklavier terminating\n" );
- XklTerm();
- } else
- {
- fprintf( stderr, "Could not init Xklavier: %s\n", XklGetLastError() );
- exit(2);
- }
- printf( "closing display: %p\n", dpy );
- XCloseDisplay(dpy);
- return 0;
+ dpy = XOpenDisplay(NULL);
+ if (dpy == NULL) {
+ fprintf(stderr, "Could not open display\n");
+ exit(1);
+ }
+ if (debug_level != -1)
+ xkl_set_debug_level(debug_level);
+ XklEngine *engine = xkl_engine_get_instance(dpy);
+ if (engine != NULL) {
+ XklConfigRec *current_config, *r2;
+ xkl_debug(0, "Xklavier initialized\n");
+ XklConfigRegistry *config =
+ xkl_config_registry_get_instance(engine);
+ xkl_config_registry_load(config);
+ xkl_debug(0, "Xklavier registry loaded\n");
+ xkl_debug(0, "Backend: [%s]\n",
+ xkl_engine_get_backend_name(engine));
+ xkl_debug(0, "Supported features: 0x0%X\n",
+ xkl_engine_get_features(engine));
+ xkl_debug(0, "Max number of groups: %d\n",
+ xkl_engine_get_max_num_groups(engine));
+
+ current_config = xkl_config_rec_new();
+ xkl_config_rec_get_from_server(current_config, engine);
+
+ switch (action) {
+ case ACTION_GET:
+ xkl_debug(0, "Got config from the server\n");
+ xkl_config_rec_dump(stdout, current_config);
+
+ r2 = xkl_config_rec_new();
+
+ if (xkl_config_rec_get_from_backup(r2, engine)) {
+ xkl_debug(0,
+ "Got config from the backup\n");
+ xkl_config_rec_dump(stdout, r2);
+ }
+
+ if (xkl_config_rec_activate(r2, engine)) {
+ xkl_debug(0,
+ "The backup configuration restored\n");
+ if (xkl_config_rec_activate
+ (current_config, engine)) {
+ xkl_debug(0,
+ "Reverting the configuration change\n");
+ } else {
+ xkl_debug(0,
+ "The configuration could not be reverted: %s\n",
+ xkl_get_last_error());
+ }
+ } else {
+ xkl_debug(0,
+ "The backup configuration could not be restored: %s\n",
+ xkl_get_last_error());
+ }
+
+ g_object_unref(G_OBJECT(r2));
+ break;
+ case ACTION_SET:
+ if (model != NULL) {
+ if (current_config->model != NULL)
+ g_free(current_config->model);
+ current_config->model = g_strdup(model);
+ }
+
+ if (layouts != NULL) {
+ if (current_config->layouts != NULL)
+ g_strfreev(current_config->
+ layouts);
+ if (current_config->variants != NULL)
+ g_strfreev(current_config->
+ variants);
+
+ current_config->layouts =
+ g_new0(char *, 2);
+ current_config->layouts[0] =
+ g_strdup(layouts);
+ current_config->variants =
+ g_new0(char *, 2);
+ current_config->variants[0] = g_strdup("");
+ }
+
+ if (options != NULL) {
+ if (current_config->options != NULL)
+ g_strfreev(current_config->
+ options);
+
+ current_config->options =
+ g_new0(char *, 2);
+ current_config->options[0] =
+ g_strdup(options);
+ }
+
+ xkl_debug(0, "New config:\n");
+ xkl_config_rec_dump(stdout, current_config);
+ if (xkl_config_rec_activate
+ (current_config, engine))
+ xkl_debug(0, "Set the config\n");
+ else
+ xkl_debug(0,
+ "Could not set the config: %s\n",
+ xkl_get_last_error());
+ break;
+ case ACTION_WRITE:
+ xkl_config_rec_write_to_file(engine,
+ binary ? (PACKAGE
+ ".xkm")
+ : (PACKAGE ".xkb"),
+ current_config,
+ binary);
+ xkl_debug(0, "The file " PACKAGE "%s is written\n",
+ binary ? ".xkm" : ".xkb");
+ break;
+ }
+
+ g_object_unref(G_OBJECT(current_config));
+
+ xkl_config_registry_free(config);
+ g_object_unref(G_OBJECT(config));
+ xkl_debug(0, "Xklavier registry freed\n");
+ xkl_debug(0, "Xklavier terminating\n");
+ g_object_unref(G_OBJECT(engine));
+ } else {
+ fprintf(stderr, "Could not init _xklavier\n");
+ exit(2);
+ }
+ printf("closing display: %p\n", dpy);
+ XCloseDisplay(dpy);
+ return 0;
}
diff --git a/tests/test_monitor.c b/tests/test_monitor.c
index 515c328..6928222 100644
--- a/tests/test_monitor.c
+++ b/tests/test_monitor.c
@@ -6,103 +6,120 @@
#include <X11/Xutil.h>
#include <X11/XKBlib.h>
#include <libxklavier/xklavier.h>
-#include <libxklavier/xklavier_config.h>
-extern void XklConfigDump( FILE* file,
- XklConfigRecPtr data );
+extern void xkl_config_dump(FILE * file, XklConfigRec * data);
-static void printUsage()
+static void
+print_usage()
{
- printf( "Usage: test_monitor (-l1)(-l2)(-l3)(-h)(-d <debugLevel>)\n" );
- printf( "Options:\n" );
- printf( " -d - Set the debug level (by default, 0)\n" );
- printf( " -h - Show this help\n" );
- printf( " -l1 - listen to manage layouts\n" );
- printf( " -l2 - listen to manage window states\n" );
- printf( " -l3 - listen to track the keyboard state\n" );
+ printf
+ ("Usage: test_monitor (-l1)(-l2)(-l3)(-h)(-d <debugLevel>)\n");
+ printf("Options:\n");
+ printf(" -d - Set the debug level (by default, 0)\n");
+ printf(" -h - Show this help\n");
+ printf(" -l1 - listen to manage layouts\n");
+ printf(" -l2 - listen to manage window states\n");
+ printf(" -l3 - listen to track the keyboard state\n");
}
-int main( int argc, char * argv[] )
+void
+state_changed(XklEngine * engine, XklEngineStateChange type, gint new_group,
+ gboolean restore)
{
- int c;
- int debugLevel = -1;
- XkbEvent ev;
- Display* dpy;
- int listenerType = 0, lt;
- int listenerTypes[] = { XKLL_MANAGE_LAYOUTS,
- XKLL_MANAGE_WINDOW_STATES,
- XKLL_TRACK_KEYBOARD_STATE };
+ xkl_debug(0, "State changed: %d,%d,%d\n", type, new_group,
+ restore);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int c;
+ int debug_level = -1;
+ XkbEvent ev;
+ Display *dpy;
+ int listener_type = 0, lt;
+ int listener_types[] = { XKLL_MANAGE_LAYOUTS,
+ XKLL_MANAGE_WINDOW_STATES,
+ XKLL_TRACK_KEYBOARD_STATE
+ };
+
+ g_type_init_with_debug_flags(G_TYPE_DEBUG_OBJECTS |
+ G_TYPE_DEBUG_SIGNALS);
+
+ while (1) {
+ c = getopt(argc, argv, "hd:l:");
+ if (c == -1)
+ break;
+ switch (c) {
+ case 'h':
+ print_usage();
+ exit(0);
+ case 'd':
+ debug_level = atoi(optarg);
+ break;
+ case 'l':
+ lt = optarg[0] - '1';
+ if (lt >= 0
+ && lt <
+ sizeof(listener_types) /
+ sizeof(listener_types[0]))
+ listener_type |= listener_types[lt];
+ break;
+ default:
+ fprintf(stderr,
+ "?? getopt returned character code 0%o ??\n",
+ c);
+ print_usage();
+ exit(0);
+ }
+ }
- while (1)
- {
- c = getopt( argc, argv, "hd:l:" );
- if ( c == -1 )
- break;
- switch (c)
- {
- case 'h':
- printUsage();
- exit(0);
- case 'd':
- debugLevel = atoi( optarg );
- break;
- case 'l':
- lt = optarg[0] - '1';
- if( lt >= 0 && lt < sizeof(listenerTypes)/sizeof(listenerTypes[0]) )
- listenerType |= listenerTypes[lt];
- break;
- default:
- fprintf( stderr, "?? getopt returned character code 0%o ??\n", c );
- printUsage();
- exit(0);
- }
- }
+ dpy = XOpenDisplay(NULL);
+ if (dpy == NULL) {
+ fprintf(stderr, "Could not open display\n");
+ exit(1);
+ }
+ if (debug_level != -1)
+ xkl_set_debug_level(debug_level);
+ XklEngine *engine = xkl_engine_get_instance(dpy);
+ if (engine != NULL) {
+ XklConfigRec *current_config;
+ xkl_debug(0, "Xklavier initialized\n");
+ XklConfigRegistry *config =
+ xkl_config_registry_get_instance(engine);
+ xkl_config_registry_load(config);
+ xkl_debug(0, "Xklavier registry loaded\n");
- dpy = XOpenDisplay( NULL );
- if ( dpy == NULL )
- {
- fprintf( stderr, "Could not open display\n" );
- exit(1);
- }
- printf( "opened display: %p\n", dpy );
- if( !XklInit( dpy ) )
- {
- XklConfigRec currentConfig;
- if( debugLevel != -1 )
- XklSetDebugLevel( debugLevel );
- XklDebug( 0, "Xklavier initialized\n" );
- XklConfigInit();
- XklConfigLoadRegistry();
- XklDebug( 0, "Xklavier registry loaded\n" );
+ current_config = xkl_config_rec_new();
+ xkl_config_rec_get_from_server(current_config, engine);
- XklConfigRecInit( &currentConfig );
- XklConfigGetFromServer( &currentConfig );
+ g_signal_connect(engine, "X-state-changed",
+ G_CALLBACK(state_changed), NULL);
- XklDebug( 0, "Now, listening...\n" );
- XklStartListen( listenerType );
+ xkl_debug(0, "Now, listening: %X...\n", listener_type);
+ xkl_engine_start_listen(engine, listener_type);
- while (1)
- {
- XNextEvent( dpy, &ev.core );
- if ( XklFilterEvents( &ev.core ) )
- XklDebug( 200, "Unknown event %d\n", ev.type );
- }
+ while (1) {
+ XNextEvent(dpy, &ev.core);
+ if (xkl_engine_filter_events(engine, &ev.core))
+ xkl_debug(200, "Unknown event %d\n",
+ ev.type);
+ }
- XklStopListen();
+ xkl_engine_stop_listen(engine);
- XklConfigRecDestroy( &currentConfig );
+ g_object_unref(G_OBJECT(current_config));
- XklConfigFreeRegistry();
- XklConfigTerm();
- XklDebug( 0, "Xklavier registry freed\n" );
- XklDebug( 0, "Xklavier terminating\n" );
- XklTerm();
- } else
- {
- fprintf( stderr, "Could not init Xklavier: %s\n", XklGetLastError() );
- exit(2);
- }
- printf( "closing display: %p\n", dpy );
- XCloseDisplay(dpy);
- return 0;
+ xkl_config_registry_free(config);
+ g_object_unref(G_OBJECT(config));
+ xkl_debug(0, "Xklavier registry freed\n");
+ xkl_debug(0, "Xklavier terminating\n");
+ g_object_unref(G_OBJECT(engine));
+ } else {
+ fprintf(stderr, "Could not init Xklavier\n");
+ exit(2);
+ }
+ printf("closing display: %p\n", dpy);
+ XCloseDisplay(dpy);
+ return 0;
}