From: Kibum Kim Date: Fri, 6 Jan 2012 16:09:46 +0000 (+0900) Subject: Git init X-Git-Tag: 2.0_alpha~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cf276784e49975be2e5a196acf4be5c2dc442622;p=framework%2Fuifw%2Fxorg%2Fxcb%2Fxcb-util.git Git init --- diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..ffb0602 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,1305 @@ +# Doxyfile 1.5.3-20071008 + +# 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 +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file that +# follow. The default is UTF-8 which is also the encoding used for all text before +# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into +# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of +# possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = XCBUtility + +# 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 = + +# 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: +# Afrikaans, Arabic, 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, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, +# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# 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 regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_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 the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = 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 = 2 + +# 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 = YES + +# 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 + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# 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 + +# 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 = NO + +# 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 this flag is set to YES, the members of anonymous namespaces will be extracted +# and appear in the documentation as a namespace called 'anonymous_namespace{file}', +# where file will be replaced with the base name of the file that contains the anonymous +# namespace. By default anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = 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 = YES + +# 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 = YES + +# 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 = YES + +# 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 = NO + +# 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 = NO + +# 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. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# 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 + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# 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. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text " + +# 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 = xcb_util_intro \ + event/ \ + icccm/ \ + image/ \ + property/ \ + reply/ + +# This tag can be used to specify the character encoding of the source files that +# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default +# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. +# See http://www.gnu.org/software/libiconv for the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# 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 *.py + +FILE_PATTERNS = + +# 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. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the output. +# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, +# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# 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 = doc/img + +# 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 , where +# is the value of the INPUT_FILTER tag, and 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. If you have enabled CALL_GRAPH or CALLER_GRAPH +# then you must also enable this option. If you don't then doxygen will produce +# a warning and turn it on anyway + +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 REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# 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 = NO + +#--------------------------------------------------------------------------- +# 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 = YES + +# 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 = 2 + +# 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 = html + +# 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 HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = 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 = 1 + +# 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 = YES + +# 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 = latex + +# 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 = YES + +# 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 = rtf + +# 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 = YES + +# 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 = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# 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 = YES + +#--------------------------------------------------------------------------- +# 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 = YES + +# 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_DEFINED 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 = NO + +# 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 = /usr/bin/perl + +#--------------------------------------------------------------------------- +# 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 = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to +# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to +# specify the directory where the mscgen tool resides. If left empty the tool is assumed to +# be found in the default search path. + +MSCGEN_PATH = + +# 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 = NO + +# 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 = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = 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 = NO + +# 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 = NO + +# If the CALL_GRAPH, SOURCE_BROWSER 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 CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will +# generate a caller 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 caller graphs for selected +# functions only using the \callergraph command. + +CALLER_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 = NO + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = 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 in 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_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the number +# of direct children of the root node in a graph is already larger than +# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# 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 the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = YES + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# 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 new file mode 100644 index 0000000..5a98062 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,6 @@ + +MAINTAINERCLEANFILES = Makefile.in + +SUBDIRS = atom aux event property icccm image keysyms reply renderutil + +EXTRA_DIST=xcb-util-common.h diff --git a/README b/README new file mode 100644 index 0000000..534a0be --- /dev/null +++ b/README @@ -0,0 +1,41 @@ +About XCB util +============== + +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + +These libraries are currently included, roughly ordered by maturity: + +render-util: Convenience functions for the Render extension. +aux: Convenient access to connection setup and some core requests. +atom: Standard core X atom constants and atom caching. +property: Callback X property-change handling. +icccm: Both client and window-manager helpers for ICCCM. +keysyms: Standard X key constants and conversion to/from keycodes. +event: Callback X event handling. +image: Port of Xlib's XImage and XShmImage functions. + +If you find any of these libraries useful, please let us know what +you're using and why you aren't in a mental hospital yet. We'd welcome +patches/suggestions for enhancement and new libraries; Please report any +issues you find to the freedesktop.org bug tracker, at: + + + +Discussion about XCB occurs on the XCB mailing list: + + + + +You can obtain the latest development versions of XCB using GIT. +For anonymous checkouts, use: + + git clone git://anongit.freedesktop.org/git/xcb/util + +For developers, use: + + git clone git+ssh://git.freedesktop.org/git/xcb/util diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 0000000..72233c7 --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,173 @@ +# =========================================================================== +# http://www.nongnu.org/autoconf-archive/ax_compare_version.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) +# +# DESCRIPTION +# +# This macro compares two version strings. Due to the various number of +# minor-version numbers that can exist, and the fact that string +# comparisons are not compatible with numeric comparisons, this is not +# necessarily trivial to do in a autoconf script. This macro makes doing +# these comparisons easy. +# +# The six basic comparisons are available, as well as checking equality +# limited to a certain number of minor-version levels. +# +# The operator OP determines what type of comparison to do, and can be one +# of: +# +# eq - equal (test A == B) +# ne - not equal (test A != B) +# le - less than or equal (test A <= B) +# ge - greater than or equal (test A >= B) +# lt - less than (test A < B) +# gt - greater than (test A > B) +# +# Additionally, the eq and ne operator can have a number after it to limit +# the test to that number of minor versions. +# +# eq0 - equal up to the length of the shorter version +# ne0 - not equal up to the length of the shorter version +# eqN - equal up to N sub-version levels +# neN - not equal up to N sub-version levels +# +# When the condition is true, shell commands ACTION-IF-TRUE are run, +# otherwise shell commands ACTION-IF-FALSE are run. The environment +# variable 'ax_compare_version' is always set to either 'true' or 'false' +# as well. +# +# Examples: +# +# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8]) +# AX_COMPARE_VERSION([3.15],[lt],[3.15.8]) +# +# would both be true. +# +# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8]) +# AX_COMPARE_VERSION([3.15],[gt],[3.15.8]) +# +# would both be false. +# +# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8]) +# +# would be true because it is only comparing two minor versions. +# +# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15]) +# +# would be true because it is only comparing the lesser number of minor +# versions of the two values. +# +# Note: The characters that separate the version numbers do not matter. An +# empty string is the same as version 0. OP is evaluated by autoconf, not +# configure, so must be a string, not a variable. +# +# The author would like to acknowledge Guido Draheim whose advice about +# the m4_case and m4_ifvaln functions make this macro only include the +# portions necessary to perform the specific comparison specified by the +# OP argument in the final configure script. +# +# LICENSE +# +# Copyright (c) 2008 Tim Toolan +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +dnl ######################################################################### +AC_DEFUN([AX_COMPARE_VERSION], [ + + # Used to indicate true or false condition + ax_compare_version=false + + # Convert the two version strings to be compared into a format that + # allows a simple string comparison. The end result is that a version + # string of the form 1.12.5-r617 will be converted to the form + # 0001001200050617. In other words, each number is zero padded to four + # digits, and non digits are removed. + AS_VAR_PUSHDEF([A],[ax_compare_version_A]) + A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ + -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/[[^0-9]]//g'` + + AS_VAR_PUSHDEF([B],[ax_compare_version_B]) + B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ + -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/[[^0-9]]//g'` + + dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary + dnl # then the first line is used to determine if the condition is true. + dnl # The sed right after the echo is to remove any indented white space. + m4_case(m4_tolower($2), + [lt],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"` + ], + [gt],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"` + ], + [le],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"` + ], + [ge],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"` + ],[ + dnl Split the operator from the subversion count if present. + m4_bmatch(m4_substr($2,2), + [0],[ + # A count of zero means use the length of the shorter version. + # Determine the number of characters in A and B. + ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'` + ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'` + + # Set A to no more than B's length and B to no more than A's length. + A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"` + B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"` + ], + [[0-9]+],[ + # A count greater than zero means use only that many subversions + A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` + B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` + ], + [.+],[ + AC_WARNING( + [illegal OP numeric parameter: $2]) + ],[]) + + # Pad zeros at end of numbers to make same length. + ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`" + B="$B`echo $A | sed 's/./0/g'`" + A="$ax_compare_version_tmp_A" + + # Check for equality or inequality as necessary. + m4_case(m4_tolower(m4_substr($2,0,2)), + [eq],[ + test "x$A" = "x$B" && ax_compare_version=true + ], + [ne],[ + test "x$A" != "x$B" && ax_compare_version=true + ],[ + AC_WARNING([illegal OP parameter: $2]) + ]) + ]) + + AS_VAR_POPDEF([A])dnl + AS_VAR_POPDEF([B])dnl + + dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE. + if test "$ax_compare_version" = "true" ; then + m4_ifvaln([$4],[$4],[:])dnl + m4_ifvaln([$5],[else $5])dnl + fi +]) dnl AX_COMPARE_VERSION diff --git a/atom/Makefile.am b/atom/Makefile.am new file mode 100644 index 0000000..8be6e60 --- /dev/null +++ b/atom/Makefile.am @@ -0,0 +1,29 @@ + +MAINTAINERCLEANFILES = Makefile.in + +lib_LTLIBRARIES = libxcb-atom.la + +xcbinclude_HEADERS = xcb_atom.h + +AM_CFLAGS = $(CWARNFLAGS) + +libxcb_atom_la_SOURCES = atoms.c atomlist.m4 atoms.gperf.m4 xcb_atom.h.m4 +libxcb_atom_la_CPPFLAGS = $(XCB_CFLAGS) +libxcb_atom_la_LIBADD = $(XCB_LIBS) +libxcb_atom_la_LDFLAGS = -version-info 1:0:0 + +pkgconfig_DATA = xcb-atom.pc + +EXTRA_DIST = xcb-atom.pc.in + +BUILT_SOURCES = atoms.c atoms.gperf xcb_atom.h +CLEANFILES = $(BUILT_SOURCES) + +atoms.c: atoms.gperf + $(GPERF) --output-file $@ $< + +atoms.gperf: atoms.gperf.m4 atomlist.m4 + $(M4) -I$(srcdir) $< >$@ + +xcb_atom.h: xcb_atom.h.m4 atomlist.m4 + $(M4) -I$(srcdir) $< >$@ diff --git a/atom/atomlist.m4 b/atom/atomlist.m4 new file mode 100644 index 0000000..1c84740 --- /dev/null +++ b/atom/atomlist.m4 @@ -0,0 +1,71 @@ +define(`FOREACH', `ifelse(`$1', , , `DO($1) +FOREACH(shift($@))')')FOREACH( +PRIMARY, +SECONDARY, +ARC, +ATOM, +BITMAP, +CARDINAL, +COLORMAP, +CURSOR, +CUT_BUFFER0, +CUT_BUFFER1, +CUT_BUFFER2, +CUT_BUFFER3, +CUT_BUFFER4, +CUT_BUFFER5, +CUT_BUFFER6, +CUT_BUFFER7, +DRAWABLE, +FONT, +INTEGER, +PIXMAP, +POINT, +RECTANGLE, +RESOURCE_MANAGER, +RGB_COLOR_MAP, +RGB_BEST_MAP, +RGB_BLUE_MAP, +RGB_DEFAULT_MAP, +RGB_GRAY_MAP, +RGB_GREEN_MAP, +RGB_RED_MAP, +STRING, +VISUALID, +WINDOW, +WM_COMMAND, +WM_HINTS, +WM_CLIENT_MACHINE, +WM_ICON_NAME, +WM_ICON_SIZE, +WM_NAME, +WM_NORMAL_HINTS, +WM_SIZE_HINTS, +WM_ZOOM_HINTS, +MIN_SPACE, +NORM_SPACE, +MAX_SPACE, +END_SPACE, +SUPERSCRIPT_X, +SUPERSCRIPT_Y, +SUBSCRIPT_X, +SUBSCRIPT_Y, +UNDERLINE_POSITION, +UNDERLINE_THICKNESS, +STRIKEOUT_ASCENT, +STRIKEOUT_DESCENT, +ITALIC_ANGLE, +X_HEIGHT, +QUAD_WIDTH, +WEIGHT, +POINT_SIZE, +RESOLUTION, +COPYRIGHT, +NOTICE, +FONT_NAME, +FAMILY_NAME, +FULL_NAME, +CAP_HEIGHT, +WM_CLASS, +WM_TRANSIENT_FOR, +)dnl diff --git a/atom/atoms.gperf.m4 b/atom/atoms.gperf.m4 new file mode 100644 index 0000000..d26814e --- /dev/null +++ b/atom/atoms.gperf.m4 @@ -0,0 +1,202 @@ +%{ + +/* Rely on vasprintf (GNU extension) instead of vsnprintf if + possible... */ +#ifdef HAVE_VASPRINTF +#define _GNU_SOURCE +#include +#endif + +#include +#include +#include +#include "xcb_atom.h" + +define(`COUNT', 0)dnl +define(`DO', `const xcb_atom_t $1 = define(`COUNT', incr(COUNT))COUNT;')dnl +include(atomlist.m4)`'dnl +%} + +%readonly-tables +%pic +%null-strings +%enum +%includes +%compare-strncmp + +%struct-type +struct atom_map { int name; xcb_atom_t value; }; +%% +define(`COUNT', 0)dnl +define(`DO', `$1,define(`COUNT', incr(COUNT))COUNT')dnl +include(atomlist.m4)`'dnl +%% + +static const char atom_names[] = +define(`DO', ` "$1\0"')dnl +include(atomlist.m4); + +static const uint16_t atom_name_offsets[] = { +define(`OFFSET', 0)dnl +define(`DO', ` OFFSET,define(`OFFSET', eval(OFFSET+1+len($1)))')dnl +include(atomlist.m4)`'dnl +}; + +xcb_atom_t xcb_atom_get(xcb_connection_t *connection, const char *atom_name) +{ + if(atom_name == NULL) + return XCB_NONE; + xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, + xcb_intern_atom(connection, 0, strlen(atom_name), atom_name), NULL); + if(!reply) + return XCB_NONE; + xcb_atom_t atom = reply->atom; + free(reply); + return atom; +} + +xcb_atom_t xcb_atom_get_predefined(uint16_t name_len, const char *name) +{ + const struct atom_map *value = in_word_set(name, name_len); + xcb_atom_t ret = XCB_NONE; + if(value) + ret = value->value; + return ret; +} + +xcb_atom_fast_cookie_t xcb_atom_get_fast(xcb_connection_t *c, uint8_t only_if_exists, uint16_t name_len, const char *name) +{ + xcb_atom_fast_cookie_t cookie; + + if((cookie.u.atom = xcb_atom_get_predefined(name_len, name)) != XCB_NONE) + { + cookie.tag = TAG_VALUE; + return cookie; + } + + cookie.tag = TAG_COOKIE; + cookie.u.cookie = xcb_intern_atom(c, only_if_exists, name_len, name); + return cookie; +} + +xcb_atom_t xcb_atom_get_fast_reply(xcb_connection_t *c, xcb_atom_fast_cookie_t cookie, xcb_generic_error_t **e) +{ + switch(cookie.tag) + { + xcb_intern_atom_reply_t *reply; + case TAG_VALUE: + if(e) + *e = 0; + break; + case TAG_COOKIE: + reply = xcb_intern_atom_reply(c, cookie.u.cookie, e); + if(reply) + { + cookie.u.atom = reply->atom; + free(reply); + } + else + cookie.u.atom = XCB_NONE; + break; + } + return cookie.u.atom; +} + +const char *xcb_atom_get_name_predefined(xcb_atom_t atom) +{ + if(atom <= 0 || atom > (sizeof(atom_name_offsets) / sizeof(*atom_name_offsets))) + return 0; + return atom_names + atom_name_offsets[atom - 1]; +} + +int xcb_atom_get_name(xcb_connection_t *c, xcb_atom_t atom, const char **namep, int *lengthp) +{ + static char buf[100]; + const char *name = xcb_atom_get_name_predefined(atom); + int namelen; + xcb_get_atom_name_cookie_t atomc; + xcb_get_atom_name_reply_t *atomr; + if(name) + { + *namep = name; + *lengthp = strlen(name); + return 1; + } + atomc = xcb_get_atom_name(c, atom); + atomr = xcb_get_atom_name_reply(c, atomc, 0); + if(!atomr) + return 0; + namelen = xcb_get_atom_name_name_length(atomr); + if(namelen > sizeof(buf)) + namelen = sizeof(buf); + *lengthp = namelen; + memcpy(buf, xcb_get_atom_name_name(atomr), namelen); + *namep = buf; + free(atomr); + return 1; +} + +static char *makename(const char *fmt, ...) +{ + char *ret; + int n; + va_list ap; + +#ifndef HAVE_VASPRINTF + char *np; + int size = 64; + + /* First allocate 'size' bytes, should be enough usually */ + if((ret = malloc(size)) == NULL) + return NULL; + + while(1) + { + va_start(ap, fmt); + n = vsnprintf(ret, size, fmt, ap); + va_end(ap); + + if(n < 0) + return NULL; + + if(n < size) + return ret; + + size = n + 1; + if((np = realloc(ret, size)) == NULL) + { + free(ret); + return NULL; + } + + ret = np; + } +#else + va_start(ap, fmt); + n = vasprintf(&ret, fmt, ap); + va_end(ap); + + if(n < 0) + return NULL; + + return ret; +#endif +} + +char *xcb_atom_name_by_screen(const char *base, uint8_t screen) +{ + return makename("%s_S%u", base, screen); +} + +char *xcb_atom_name_by_resource(const char *base, uint32_t resource) +{ + return makename("%s_R%08X", base, resource); +} + +char *xcb_atom_name_unique(const char *base, uint32_t id) +{ + if(base) + return makename("%s_U%lu", base, id); + else + return makename("U%lu", id); +} diff --git a/atom/xcb-atom.pc.in b/atom/xcb-atom.pc.in new file mode 100644 index 0000000..b59b57f --- /dev/null +++ b/atom/xcb-atom.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: XCB Atom library +Description: XCB atom cache +Version: @PACKAGE_VERSION@ +Requires: xcb +Libs: -L${libdir} -lxcb-atom @LIBS@ +Cflags: -I${includedir} diff --git a/atom/xcb_atom.h.m4 b/atom/xcb_atom.h.m4 new file mode 100644 index 0000000..3579211 --- /dev/null +++ b/atom/xcb_atom.h.m4 @@ -0,0 +1,50 @@ +#ifndef __XCB_ATOM_H__ +#define __XCB_ATOM_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +enum xcb_atom_fast_tag_t { + TAG_COOKIE, + TAG_VALUE +}; +typedef struct { + enum xcb_atom_fast_tag_t tag; + union { + xcb_intern_atom_cookie_t cookie; + xcb_atom_t atom; + } u; +} xcb_atom_fast_cookie_t; + +/** + * @brief Get an atom synchronously. + * @param connection The connection to the X server. + * @param atom_name The name of the atom that should be returned. + * @return The requested atom, or XCB_NONE if there is an error. + * + * xcb_atom_get() is essentially a synchronous version of xcb_intern_atom(), + * use it only on non-performance critical execution paths. + */ +xcb_atom_t xcb_atom_get(xcb_connection_t *connection, const char *atom_name); +xcb_atom_t xcb_atom_get_predefined(uint16_t name_len, const char *name); +xcb_atom_fast_cookie_t xcb_atom_get_fast(xcb_connection_t *c, uint8_t only_if_exists, uint16_t name_len, const char *name); +xcb_atom_t xcb_atom_get_fast_reply(xcb_connection_t *c, xcb_atom_fast_cookie_t cookie, xcb_generic_error_t **e); + +const char *xcb_atom_get_name_predefined(xcb_atom_t atom); +int xcb_atom_get_name(xcb_connection_t *c, xcb_atom_t atom, const char **namep, int *lengthp); + +char *xcb_atom_name_by_screen(const char *base, uint8_t screen); +char *xcb_atom_name_by_resource(const char *base, uint32_t resource); +char *xcb_atom_name_unique(const char *base, uint32_t id); + +define(`DO', `extern const xcb_atom_t $1;')dnl +include(atomlist.m4)`'dnl + +#ifdef __cplusplus +} +#endif + +#endif /* __XCB_ATOM_H__ */ diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..70429df --- /dev/null +++ b/autogen.sh @@ -0,0 +1,4 @@ +#! /bin/sh +libtoolize --force +autoreconf -v --install || exit 1 +./configure "$@" diff --git a/aux/Makefile.am b/aux/Makefile.am new file mode 100644 index 0000000..56660e7 --- /dev/null +++ b/aux/Makefile.am @@ -0,0 +1,16 @@ + +MAINTAINERCLEANFILES = Makefile.in + +lib_LTLIBRARIES = libxcb-aux.la + +xcbinclude_HEADERS = xcb_aux.h xcb_bitops.h + +AM_CFLAGS = $(CWARNFLAGS) + +libxcb_aux_la_SOURCES = xcb_aux.c +libxcb_aux_la_CPPFLAGS = $(XCB_CFLAGS) +libxcb_aux_la_LIBADD = $(XCB_LIBS) + +pkgconfig_DATA = xcb-aux.pc + +EXTRA_DIST=xcb-aux.pc.in diff --git a/aux/xcb-aux.pc.in b/aux/xcb-aux.pc.in new file mode 100644 index 0000000..79ed95c --- /dev/null +++ b/aux/xcb-aux.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: XCB Aux library +Description: XCB convenient functions +Version: @PACKAGE_VERSION@ +Requires: xcb +Libs: -L${libdir} -lxcb-aux @LIBS@ +Cflags: -I${includedir} diff --git a/aux/xcb_aux.c b/aux/xcb_aux.c new file mode 100644 index 0000000..c810398 --- /dev/null +++ b/aux/xcb_aux.c @@ -0,0 +1,374 @@ +/* + * Copyright © 2008 Bart Massey + * Copyright © 2008 Ian Osgood + * Copyright © 2008 Jamey Sharp + * Copyright © 2008 Josh Triplett + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +#include +#include +#include + +#include +#include "xcb_aux.h" + +/* Connection related functions */ + +uint8_t +xcb_aux_get_depth (xcb_connection_t *c, + xcb_screen_t *screen) +{ + xcb_drawable_t drawable; + xcb_get_geometry_reply_t *geom; + int depth = 0; + + drawable = screen->root; + geom = xcb_get_geometry_reply (c, xcb_get_geometry(c, drawable), 0); + + if (geom) { + depth = geom->depth; + free (geom); + } + + return depth; +} + +uint8_t +xcb_aux_get_depth_of_visual (xcb_screen_t *screen, + xcb_visualid_t id) +{ + xcb_depth_iterator_t i; + xcb_visualtype_iterator_t j; + for (i = xcb_screen_allowed_depths_iterator(screen); + i.rem; xcb_depth_next(&i)) + for (j = xcb_depth_visuals_iterator(i.data); + j.rem; xcb_visualtype_next(&j)) + if (j.data->visual_id == id) + return i.data->depth; + return 0; +} + +xcb_screen_t * +xcb_aux_get_screen (xcb_connection_t *c, + int screen) +{ + xcb_screen_iterator_t i = xcb_setup_roots_iterator(xcb_get_setup(c)); + for (; i.rem; --screen, xcb_screen_next(&i)) + if (screen == 0) + return i.data; + return 0; +} + +xcb_visualtype_t * +xcb_aux_get_visualtype (xcb_connection_t *c, + int scr, + xcb_visualid_t vid) +{ + xcb_screen_t *screen; + xcb_depth_t *depth; + xcb_visualtype_iterator_t iter; + int cur; + + screen = xcb_aux_get_screen (c, scr); + if (!screen) return NULL; + + depth = xcb_screen_allowed_depths_iterator(screen).data; + if (!depth) return NULL; + + iter = xcb_depth_visuals_iterator(depth); + for (cur = 0 ; cur < iter.rem ; xcb_visualtype_next(&iter), ++cur) + if (vid == iter.data->visual_id) + return iter.data; + + return NULL; +} + +xcb_visualtype_t * +xcb_aux_find_visual_by_id (xcb_screen_t *screen, + xcb_visualid_t id) +{ + xcb_depth_iterator_t i; + xcb_visualtype_iterator_t j; + for (i = xcb_screen_allowed_depths_iterator(screen); + i.rem; xcb_depth_next(&i)) + for (j = xcb_depth_visuals_iterator(i.data); + j.rem; xcb_visualtype_next(&j)) + if (j.data->visual_id == id) + return j.data; + return 0; +} + +xcb_visualtype_t * +xcb_aux_find_visual_by_attrs (xcb_screen_t *screen, + int8_t class, + int8_t depth) +{ + xcb_depth_iterator_t i; + xcb_visualtype_iterator_t j; + for (i = xcb_screen_allowed_depths_iterator(screen); + i.rem; xcb_depth_next(&i)) { + if (depth != -1 && i.data->depth != depth) + continue; + for (j = xcb_depth_visuals_iterator(i.data); + j.rem; xcb_visualtype_next(&j)) + if (class == -1 || j.data->_class == class) + return j.data; + } + return 0; +} + +void +xcb_aux_sync (xcb_connection_t *c) +{ + free(xcb_get_input_focus_reply(c, xcb_get_input_focus(c), NULL)); +} + +/* structs instead of value lists */ +/* TODO: generate the struct types and functions from protocol masks and descriptions */ + +/* This generic implementation of pack_list depends on: + a) structs packed to uint32_t size + b) structs consist of just uint32_t/int32_t fields in the same order as bitmask +*/ + +static void +pack_list( uint32_t mask, const uint32_t *src, uint32_t *dest ) +{ + for ( ; mask; mask >>= 1, src++) + if (mask & 1) + *dest++ = *src; +} + +xcb_void_cookie_t +xcb_aux_create_window (xcb_connection_t *c, + uint8_t depth, + xcb_window_t wid, + xcb_window_t parent, + int16_t x, + int16_t y, + uint16_t width, + uint16_t height, + uint16_t border_width, + uint16_t _class, + xcb_visualid_t visual, + uint32_t mask, + const xcb_params_cw_t *params) +{ + uint32_t value_list[16]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_create_window(c, depth, wid, parent, + x, y, width, height, border_width, + _class, visual, mask, value_list); +} + +xcb_void_cookie_t +xcb_aux_create_window_checked (xcb_connection_t *c, + uint8_t depth, + xcb_window_t wid, + xcb_window_t parent, + int16_t x, + int16_t y, + uint16_t width, + uint16_t height, + uint16_t border_width, + uint16_t _class, + xcb_visualid_t visual, + uint32_t mask, + const xcb_params_cw_t *params) +{ + uint32_t value_list[16]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_create_window_checked(c, depth, wid, parent, + x, y, width, height, border_width, + _class, visual, mask, value_list); +} + +xcb_void_cookie_t +xcb_aux_change_window_attributes_checked (xcb_connection_t *c, + xcb_window_t window, + uint32_t mask, + const xcb_params_cw_t *params) +{ + uint32_t value_list[16]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_change_window_attributes_checked( c, window, mask, value_list ); +} + +xcb_void_cookie_t +xcb_aux_change_window_attributes (xcb_connection_t *c, + xcb_window_t window, + uint32_t mask, + const xcb_params_cw_t *params) +{ + uint32_t value_list[16]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_change_window_attributes( c, window, mask, value_list ); +} + +xcb_void_cookie_t +xcb_aux_configure_window (xcb_connection_t *c, + xcb_window_t window, + uint16_t mask, + const xcb_params_configure_window_t *params) +{ + uint32_t value_list[8]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_configure_window( c, window, mask, value_list ); +} + +xcb_void_cookie_t +xcb_aux_create_gc (xcb_connection_t *c, + xcb_gcontext_t gid, + xcb_drawable_t drawable, + uint32_t mask, + const xcb_params_gc_t *params) +{ + uint32_t value_list[32]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_create_gc( c, gid, drawable, mask, value_list ); +} + +xcb_void_cookie_t +xcb_aux_create_gc_checked (xcb_connection_t *c, + xcb_gcontext_t gid, + xcb_drawable_t drawable, + uint32_t mask, + const xcb_params_gc_t *params) +{ + uint32_t value_list[32]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_create_gc_checked( c, gid, drawable, mask, value_list); +} + +xcb_void_cookie_t +xcb_aux_change_gc (xcb_connection_t *c, + xcb_gcontext_t gc, + uint32_t mask, + const xcb_params_gc_t *params) +{ + uint32_t value_list[32]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_change_gc( c, gc, mask, value_list ); +} + +xcb_void_cookie_t +xcb_aux_change_gc_checked (xcb_connection_t *c, + xcb_gcontext_t gc, + uint32_t mask, + const xcb_params_gc_t *params) +{ + uint32_t value_list[32]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_change_gc_checked( c, gc, mask, value_list ); +} + +xcb_void_cookie_t +xcb_aux_change_keyboard_control (xcb_connection_t *c, + uint32_t mask, + const xcb_params_keyboard_t *params) +{ + uint32_t value_list[16]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_change_keyboard_control( c, mask, value_list ); +} + +/* Color related functions */ + +/* Return true if the given color name can be translated locally, + in which case load the components. Otherwise, a lookup_color request + will be needed, so return false. */ +int +xcb_aux_parse_color(char *color_name, + uint16_t *red, uint16_t *green, uint16_t *blue) +{ + int n, r, g, b, i; + if (!color_name || *color_name != '#') + return 0; + /* + * Excitingly weird RGB parsing code from Xlib. + */ + n = strlen (color_name); + color_name++; + n--; + if (n != 3 && n != 6 && n != 9 && n != 12) + return 0; + n /= 3; + g = b = 0; + do { + r = g; + g = b; + b = 0; + for (i = n; --i >= 0; ) { + char c = *color_name++; + b <<= 4; + if (c >= '0' && c <= '9') + b |= c - '0'; + else if (c >= 'A' && c <= 'F') + b |= c - ('A' - 10); + else if (c >= 'a' && c <= 'f') + b |= c - ('a' - 10); + else return 0; + } + } while (*color_name != '\0'); + n <<= 2; + n = 16 - n; + *red = r << n; + *green = g << n; + *blue = b << n; + return 1; +} + +/* Drawing related functions */ + +/* Adapted from Xlib */ +xcb_void_cookie_t +xcb_aux_set_line_attributes_checked (xcb_connection_t *dpy, + xcb_gcontext_t gc, + uint16_t linewidth, + int32_t linestyle, + int32_t capstyle, + int32_t joinstyle) +{ + uint32_t mask = 0; + xcb_params_gc_t gv; + + XCB_AUX_ADD_PARAM(&mask, &gv, line_width, linewidth); + XCB_AUX_ADD_PARAM(&mask, &gv, line_style, linestyle); + XCB_AUX_ADD_PARAM(&mask, &gv, cap_style, capstyle); + XCB_AUX_ADD_PARAM(&mask, &gv, join_style, joinstyle); + return xcb_aux_change_gc_checked(dpy, gc, mask, &gv); +} + +/* Adapted from Xlib */ +/* XXX It would be wiser for apps just to call + clear_area() directly. */ +xcb_void_cookie_t +xcb_aux_clear_window(xcb_connection_t * dpy, + xcb_window_t w) +{ + return xcb_clear_area(dpy, 0, w, 0, 0, 0, 0); +} diff --git a/aux/xcb_aux.h b/aux/xcb_aux.h new file mode 100644 index 0000000..d49d438 --- /dev/null +++ b/aux/xcb_aux.h @@ -0,0 +1,214 @@ +#ifndef __XCB_AUX_H__ +#define __XCB_AUX_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + + +uint8_t xcb_aux_get_depth (xcb_connection_t *c, + xcb_screen_t *screen); + +uint8_t xcb_aux_get_depth_of_visual (xcb_screen_t *screen, + xcb_visualid_t id); + +xcb_screen_t *xcb_aux_get_screen (xcb_connection_t *c, + int screen); + +xcb_visualtype_t *xcb_aux_get_visualtype (xcb_connection_t *c, + int screen, + xcb_visualid_t vid); + +xcb_visualtype_t * +xcb_aux_find_visual_by_id (xcb_screen_t *screen, + xcb_visualid_t id); + +xcb_visualtype_t * +xcb_aux_find_visual_by_attrs (xcb_screen_t *screen, + int8_t class_, + int8_t depth); + +void xcb_aux_sync (xcb_connection_t *c); + +/* internal helper macro for XCB_AUX_ADD_PARAM +It gives the offset of the field 'param' in the structure pointed to by +'paramsp' in multiples of an uint32_t's size. */ +#define XCB_AUX_INTERNAL_OFFSETOF(paramsp, param) \ + ((uint32_t const*)(&((paramsp)->param))-(uint32_t const*)(paramsp)) + +/* add an optional parameter to an xcb_params_* structure +parameters: + maskp: pointer to bitmask whos bits mark used parameters + paramsp: pointer to structure with parameters + param: parameter to set + value: value to set the parameter to +*/ +#define XCB_AUX_ADD_PARAM(maskp, paramsp, param, value) \ + ((*(maskp)|=1<param=(value))) + +typedef struct { + uint32_t back_pixmap; + uint32_t back_pixel; + uint32_t border_pixmap; + uint32_t border_pixel; + uint32_t bit_gravity; + uint32_t win_gravity; + uint32_t backing_store; + uint32_t backing_planes; + uint32_t backing_pixel; + uint32_t override_redirect; + uint32_t save_under; + uint32_t event_mask; + uint32_t dont_propagate; + uint32_t colormap; + uint32_t cursor; +} xcb_params_cw_t; + +xcb_void_cookie_t +xcb_aux_create_window (xcb_connection_t *c, + uint8_t depth, + xcb_window_t wid, + xcb_window_t parent, + int16_t x, + int16_t y, + uint16_t width, + uint16_t height, + uint16_t border_width, + uint16_t class_, + xcb_visualid_t visual, + uint32_t mask, + const xcb_params_cw_t *params); + +xcb_void_cookie_t +xcb_aux_create_window_checked (xcb_connection_t *c, + uint8_t depth, + xcb_window_t wid, + xcb_window_t parent, + int16_t x, + int16_t y, + uint16_t width, + uint16_t height, + uint16_t border_width, + uint16_t class_, + xcb_visualid_t visual, + uint32_t mask, + const xcb_params_cw_t *params); + +xcb_void_cookie_t +xcb_aux_change_window_attributes (xcb_connection_t *c, + xcb_window_t window, + uint32_t mask, + const xcb_params_cw_t *params); + +xcb_void_cookie_t +xcb_aux_change_window_attributes_checked (xcb_connection_t *c, + xcb_window_t window, + uint32_t mask, + const xcb_params_cw_t *params); + +typedef struct { + int32_t x; + int32_t y; + uint32_t width; + uint32_t height; + uint32_t border_width; + uint32_t sibling; + uint32_t stack_mode; +} xcb_params_configure_window_t; + +xcb_void_cookie_t +xcb_aux_configure_window (xcb_connection_t *c, + xcb_window_t window, + uint16_t mask, + const xcb_params_configure_window_t *params); + +typedef struct { + uint32_t function; + uint32_t plane_mask; + uint32_t foreground; + uint32_t background; + uint32_t line_width; + uint32_t line_style; + uint32_t cap_style; + uint32_t join_style; + uint32_t fill_style; + uint32_t fill_rule; + uint32_t tile; + uint32_t stipple; + uint32_t tile_stipple_origin_x; + uint32_t tile_stipple_origin_y; + uint32_t font; + uint32_t subwindow_mode; + uint32_t graphics_exposures; + uint32_t clip_originX; + uint32_t clip_originY; + uint32_t mask; + uint32_t dash_offset; + uint32_t dash_list; + uint32_t arc_mode; +} xcb_params_gc_t; + +xcb_void_cookie_t +xcb_aux_create_gc (xcb_connection_t *c, + xcb_gcontext_t cid, + xcb_drawable_t drawable, + uint32_t mask, + const xcb_params_gc_t *params); + +xcb_void_cookie_t +xcb_aux_create_gc_checked (xcb_connection_t *c, + xcb_gcontext_t gid, + xcb_drawable_t drawable, + uint32_t mask, + const xcb_params_gc_t *params); +xcb_void_cookie_t +xcb_aux_change_gc (xcb_connection_t *c, + xcb_gcontext_t gc, + uint32_t mask, + const xcb_params_gc_t *params); + +xcb_void_cookie_t +xcb_aux_change_gc_checked (xcb_connection_t *c, + xcb_gcontext_t gc, + uint32_t mask, + const xcb_params_gc_t *params); +typedef struct { + uint32_t key_click_percent; + uint32_t bell_percent; + uint32_t bell_pitch; + uint32_t bell_duration; + uint32_t led; + uint32_t led_mode; + uint32_t key; + uint32_t auto_repeat_mode; +} xcb_params_keyboard_t; + +xcb_void_cookie_t +xcb_aux_change_keyboard_control (xcb_connection_t *c, + uint32_t mask, + const xcb_params_keyboard_t *params); + +int +xcb_aux_parse_color(char *color_name, + uint16_t *red, uint16_t *green, uint16_t *blue); + +xcb_void_cookie_t +xcb_aux_set_line_attributes_checked (xcb_connection_t *dpy, + xcb_gcontext_t gc, + uint16_t linewidth, + int32_t linestyle, + int32_t capstyle, + int32_t joinstyle); + +xcb_void_cookie_t +xcb_aux_clear_window(xcb_connection_t * dpy, + xcb_window_t w); + +#ifdef __cplusplus +} +#endif + + +#endif /* __XCB_AUX_H__ */ diff --git a/aux/xcb_bitops.h b/aux/xcb_bitops.h new file mode 100644 index 0000000..a6872a1 --- /dev/null +++ b/aux/xcb_bitops.h @@ -0,0 +1,212 @@ +#ifndef __XCB_BITOPS_H__ +#define __XCB_BITOPS_H__ + +/* Copyright (C) 2007 Bart Massey + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or their + * institutions shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization from the authors. + */ + +#include +#include +#include + +/** + * @defgroup xcb__bitops XCB Bit Operations + * + * Inline functions for common bit ops used in XCB and elsewhere. + * + * @{ + */ + + +/** + * Create a low-order bitmask. + * @param n Mask size. + * @return Mask. + * + * Create a bitmask with the lower @p n bits set and the + * rest of the word clear. + * @ingroup xcb__bitops + */ +_X_INLINE static uint32_t +xcb_mask(uint32_t n) +{ + return n == 32 ? ~0 : (1 << n) - 1; +} + + +/** + * Population count. + * @param n Integer representing a bitset. + * @return Number of 1 bits in the bitset. + * + * This is a reasonably fast algorithm for counting the bits + * in a 32-bit word. Currently a classic binary + * divide-and-conquer popcount: popcount_2() from + * http://en.wikipedia.org/wiki/Hamming_weight. + * @ingroup xcb__bitops + */ + + +/* 15 ops, 3 long immediates, 14 stages, 9 alu ops, 9 alu stages */ +_X_INLINE static uint32_t +xcb_popcount(uint32_t x) +{ + uint32_t m1 = 0x55555555; + uint32_t m2 = 0x33333333; + uint32_t m4 = 0x0f0f0f0f; + x -= (x >> 1) & m1; + x = (x & m2) + ((x >> 2) & m2); + x = (x + (x >> 4)) & m4; + x += x >> 8; + return (x + (x >> 16)) & 0x3f; +} + + +/** + * Round up to the next power-of-two unit size. + * @param base Number to be rounded up. + * @param pad Multiple to be rounded to; must be a power of two. + * @return Rounded-up number. + * + * Rounds @p base up to a multiple of @p pad, where @p pad + * is a power of two. The more general case is handled by + * xcb_roundup(). + * @ingroup xcb__bitops + */ +_X_INLINE static uint32_t +xcb_roundup_2 (uint32_t base, uint32_t pad) +{ + return (base + pad - 1) & -pad; +} + +/** + * Round down to the next power-of-two unit size. + * @param base Number to be rounded down. + * @param pad Multiple to be rounded to; must be a power of two. + * @return Rounded-down number. + * + * Rounds @p base down to a multiple of @p pad, where @p pad + * is a power of two. The more general case is handled by + * xcb_rounddown(). + * @ingroup xcb__bitops + */ +_X_INLINE static uint32_t +xcb_rounddown_2 (uint32_t base, uint32_t pad) +{ + return base & -pad; +} + +/** + * Round up to the next unit size. + * @param base Number to be rounded up. + * @param pad Multiple to be rounded to. + * @return Rounded-up number. + * + * This is a general routine for rounding @p base up + * to a multiple of @p pad. If you know that @p pad + * is a power of two, you should probably call xcb_roundup_2() + * instead. + * @ingroup xcb__bitops + */ +_X_INLINE static uint32_t +xcb_roundup (uint32_t base, uint32_t pad) +{ + uint32_t b = base + pad - 1; + /* faster if pad is a power of two */ + if (((pad - 1) & pad) == 0) + return b & -pad; + return b - b % pad; +} + + +/** + * Round down to the next unit size. + * @param base Number to be rounded down. + * @param pad Multiple to be rounded to. + * @return Rounded-down number. + * + * This is a general routine for rounding @p base down + * to a multiple of @p pad. If you know that @p pad + * is a power of two, you should probably call xcb_rounddown_2() + * instead. + * @ingroup xcb__bitops + */ +_X_INLINE static uint32_t +xcb_rounddown (uint32_t base, uint32_t pad) +{ + /* faster if pad is a power of two */ + if (((pad - 1) & pad) == 0) + return base & -pad; + return base - base % pad; +} + + +/** + * Reverse bits of word. + * @param x Target word. + * @param n Number of low-order bits to reverse. + * @return Word with low @p n bits reversed, all others 0. + * + * Reverses the bottom @p n bits of @p x. + * @ingroup xcb__bitops + */ +_X_INLINE static uint32_t +xcb_bit_reverse(uint32_t x, uint8_t n) { + uint32_t m1 = 0x00ff00ff; + uint32_t m2 = 0x0f0f0f0f; + uint32_t m3 = 0x33333333; + uint32_t m4 = 0x55555555; + x = ((x << 16) | (x >> 16)); + x = ((x & m1) << 8) | ((x >> 8) & m1); + x = ((x & m2) << 4) | ((x >> 4) & m2); + x = ((x & m3) << 2) | ((x >> 2) & m3); + x = ((x & m4) << 1) | ((x >> 1) & m4); + x >>= 32 - n; + return x; +} + + +/** + * Host byte order. + * @return The byte order of the host. + * + * Tests the host's byte order and returns either + * XCB_IMAGE_ORDER_MSB_FIRST or XCB_IMAGE_ORDER_LSB_FIRST + * as appropriate. + * @ingroup xcb__bitops + */ +_X_INLINE static xcb_image_order_t +xcb_host_byte_order(void) { + uint32_t endian_test = 0x01020304; + + switch (*(char *)&endian_test) { + case 0x01: + return XCB_IMAGE_ORDER_MSB_FIRST; + case 0x04: + return XCB_IMAGE_ORDER_LSB_FIRST; + } + assert(0); +} + +#endif /* __XCB_BITOPS_H__ */ diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..75a89d1 --- /dev/null +++ b/configure.ac @@ -0,0 +1,110 @@ +dnl AC_TYPE_SSIZE_T is defined from 2.59c +AC_PREREQ(2.59c) +AC_INIT([xcb-util],0.3.6,[xcb@lists.freedesktop.org]) +AC_CONFIG_SRCDIR([Makefile.am]) +AM_INIT_AUTOMAKE([foreign dist-bzip2]) + +AC_CHECK_PROGS(M4, [m4 gm4], [no]) +if test $M4 != "no" ; then + AC_MSG_CHECKING([if $M4 supports -I]) + if $M4 -I. /dev/null > /dev/null 2>&1 ; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + # Try finding the gnu version + AC_CHECK_PROGS(GM4, gm4, [no]) + if test $GM4 = "no" ; then + AC_PATH_PROGS(GNUM4, m4, [no], [/usr/gnu/bin]) + M4="$GNUM4" + else + M4="$GM4" + fi + fi +fi +if test $M4 = "no"; then + AC_MSG_ERROR([Can't find usable m4, please install it and try again]) +fi +AC_CHECK_PROGS(GPERF, gperf, [no]) +if test $GPERF = "no"; then + AC_MSG_ERROR([Can't find gperf, please install it and try again]) +fi +AC_PROG_CC +AC_PROG_LIBTOOL + +if test "x$GCC" = xyes ; then + CWARNFLAGS="-Wall" +else + AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"]) + if test "x$SUNCC" = "xyes"; then + CWARNFLAGS="-v" + fi +fi +AC_SUBST(CWARNFLAGS) +AC_CHECK_FUNCS_ONCE(vasprintf) + +dnl Checking whether ssize_t is defined (xcb-util-common.h) +AC_TYPE_SSIZE_T + +xcbincludedir='${includedir}/xcb' +AC_SUBST(xcbincludedir) + +pkgconfigdir='${libdir}/pkgconfig' +AC_SUBST(pkgconfigdir) + +PKG_CHECK_MODULES(XCB, xcb >= 1.4) + +###### +# Check version of xcb-proto that xcb was compiled against +###### +xcbproto_required=1.5 + +# Moved from AX_COMPARE_VERSION to maintain proper output +AC_PROG_AWK + +AC_MSG_CHECKING([whether libxcb was compiled against xcb-proto >= $xcbproto_required]) +xcbproto_version=`$PKG_CONFIG --variable=xcbproto_version xcb` +AX_COMPARE_VERSION([$xcbproto_version],[ge],[$xcbproto_required], xcbproto_ok="yes", xcbproto_ok="no") +AC_MSG_RESULT([$xcbproto_ok]) + +if test $xcbproto_ok = no; then + AC_MSG_ERROR([libxcb was compiled against xcb-proto $xcbproto_version; it needs to be compiled against version $xcbproto_required or higher]) +fi + + +PKG_CHECK_MODULES(XCB_SHM, xcb-shm) +PKG_CHECK_MODULES(XCB_RENDER, xcb-render) +PKG_CHECK_MODULES(XPROTO, xproto >= 7.0.8) + +XCB_AUX_CFLAGS='-I$(top_srcdir)/aux' +XCB_AUX_LIBS='$(top_builddir)/aux/libxcb-aux.la' +XCB_ATOM_CFLAGS='-I$(top_srcdir)/atom -I$(top_builddir)/atom' +XCB_ATOM_LIBS='$(top_builddir)/atom/libxcb-atom.la' +XCB_EVENT_CFLAGS='-I$(top_srcdir)/event' +XCB_EVENT_LIBS='$(top_builddir)/event/libxcb-event.la' +XCB_PROPERTY_CFLAGS='-I$(top_srcdir)/property' +XCB_PROPERTY_LIBS='$(top_builddir)/property/libxcb-property.la' +XCB_ICCCM_CFLAGS='-I$(top_srcdir)/icccm' +XCB_ICCCM_LIBS='$(top_builddir)/icccm/libxcb-icccm.la' +AC_SUBST(XCB_AUX_CFLAGS) +AC_SUBST(XCB_AUX_LIBS) +AC_SUBST(XCB_ATOM_CFLAGS) +AC_SUBST(XCB_ATOM_LIBS) +AC_SUBST(XCB_EVENT_CFLAGS) +AC_SUBST(XCB_EVENT_LIBS) +AC_SUBST(XCB_PROPERTY_CFLAGS) +AC_SUBST(XCB_PROPERTY_LIBS) +AC_SUBST(XCB_ICCCM_CFLAGS) +AC_SUBST(XCB_ICCCM_LIBS) + +AC_OUTPUT([Makefile + aux/Makefile aux/xcb-aux.pc + reply/Makefile reply/xcb-reply.pc + image/Makefile image/xcb-image.pc + atom/Makefile atom/xcb-atom.pc + event/Makefile event/xcb-event.pc + keysyms/Makefile keysyms/xcb-keysyms.pc + property/Makefile property/xcb-property.pc + icccm/Makefile icccm/xcb-icccm.pc + renderutil/Makefile renderutil/xcb-renderutil.pc + xcb_util_intro + ]) diff --git a/debian/changelog b/debian/changelog new file mode 100755 index 0000000..ce54ef8 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,181 @@ +xcb-util (0.3.6-8slp2) unstable; urgency=low + + * [X11R7.6] upgrade package + * Git: 165.213.180.234:slp/pkgs/xorg/xcb/xcb-util + * Tag: xcb-util_0.3.6-8slp2 + + -- SooChan Lim Thu, 06 Jan 2011 14:09:53 +0900 + +xcb-util (0.3.6-7slp2) unstable; urgency=low + + * Add --as-needed option (omitted from previous commit) + * Git: 165.213.180.234:/git/slp/pkgs/xorg/xcb/xcb-util + * Tag: xcb-util_0.3.6-7slp2 + + -- Sung-Jin Park Mon, 22 Nov 2010 19:21:57 +0900 + +xcb-util (0.3.6-6slp2) unstable; urgency=low + + * Add following debug packages + - libxcb-atom1-dbg + - libxcb-aux0-dbg + - libxcb-event1-dbg + - libxcb-image0-dbg + - libxcb-keysyms1-dbg + - libxcb-property1-dbg + - libxcb-render-util0-dbg + - libxcb-reply1-dbg + - libxcb-icccm1-dbg + * Git: 165.213.180.234:/git/slp/pkgs/xorg/xcb/xcb-util + * Tag: xcb-util_0.3.6-6slp2 + + -- Sung-Jin Park Mon, 22 Nov 2010 18:12:59 +0900 + +xcb-util (0.3.6-5slp2) unstable; urgency=low + + * add --as-needed + * Git: 165.213.180.234:/git/slp/pkgs/xorg/xcb/xcb-util + * Tag: xcb-util_0.3.6-5slp2 + + -- SoocChan Lim Thu, 18 Nov 2010 14:51:16 +0900 + +xcb-util (0.3.6-4slp2) unstable; urgency=low + + * Relax build dependency on gperf-dev to gperf | gperf-dev + (gperf is actually the proper package name). + + -- Rafal Krypa Tue, 07 Sep 2010 21:28:13 +0900 + +xcb-util (0.3.6-3slp2) unstable; urgency=low + + * Update maintainer + * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/X11 + * Tag: xcb-util_0.3.6-3slp2 + + -- Sung-Jin Park Wed, 21 Apr 2010 11:46:40 +0900 + +xcb-util (0.3.6-2slp2) unstable; urgency=low + + * Change revision + + -- Sung-Jin Park Thu, 25 Mar 2010 19:00:15 +0900 + +xcb-util (0.3.6-1build1) lucid; urgency=low + + * rebuild rest of main for armel armv7/thumb2 optimization; + UbuntuSpec:mobile-lucid-arm-gcc-v7-thumb2 + + -- Alexander Sack Sun, 07 Mar 2010 01:11:50 +0100 + +xcb-util (0.3.6-1) unstable; urgency=low + + * New upstream release + * Bump standard version + + -- Julien Danjou Mon, 24 Aug 2009 10:55:14 +0200 + +xcb-util (0.3.5-1) unstable; urgency=low + + * New upstream release + + -- Julien Danjou Fri, 29 May 2009 11:51:03 +0200 + +xcb-util (0.3.4-1) unstable; urgency=low + + * New upstream release + + Bump version of keysyms + + Remove wm library + * Bump standard version + + -- Julien Danjou Wed, 15 Apr 2009 16:04:31 +0200 + +xcb-util (0.3.3-2) unstable; urgency=low + + * Add versioned link to GPL. + + -- Julien Danjou Sun, 15 Feb 2009 12:58:13 +0100 + +xcb-util (0.3.3-1) experimental; urgency=low + + * New upstream release + + -- Julien Danjou Sat, 31 Jan 2009 15:56:59 +0100 + +xcb-util (0.3.2-1) experimental; urgency=low + + * New upstream release + * Add ${misc:Depends} on -dev packages + + -- Julien Danjou Tue, 16 Dec 2008 14:47:17 +0100 + +xcb-util (0.3.1-2) experimental; urgency=low + + * Add sh in front of autogen.sh (Closes: #506393) + + -- Julien Danjou Fri, 21 Nov 2008 10:17:40 +0100 + +xcb-util (0.3.1-1) experimental; urgency=low + + * New upstream release + + -- Julien Danjou Thu, 20 Nov 2008 16:15:51 +0100 + +xcb-util (0.3.0-2) experimental; urgency=low + + * Add x11proto-core-dev versioned to build-dep (Closes: #505336) + + -- Julien Danjou Tue, 11 Nov 2008 21:09:06 +0100 + +xcb-util (0.3.0-1) experimental; urgency=low + + * New upstream release + + -- Julien Danjou Wed, 17 Sep 2008 15:04:55 +0200 + +xcb-util (0.2.1+git1-1) unstable; urgency=low + + * New git snapshot + * dh_makeshlibs get a -V + + -- Julien Danjou Wed, 06 Aug 2008 17:44:13 +0200 + +xcb-util (0.2+git41-1) unstable; urgency=low + + * New git snapshot + * Fix sections, set libs for libs packages and libdevel for + -dev packages (Closes: #491534) + + -- Julien Danjou Tue, 22 Jul 2008 10:02:18 +0200 + +xcb-util (0.2+git36-1) unstable; urgency=low + + [ Arnaud Fontaine ] + * debian/control: + + Add missing dependencies to libxcb*-dev packages. Closes: #480524. + * patches: + + Add icccm_remove_useless_functions patch which removes useless + function for accessing 'flags' which were also buggy because they + were returning a 'uint8_t' whereas 'flags' is a 'uint32_t'. + + Add icccm_fix_incorrect_copy which correctly copies the + reply value according to its format. + + Add icccm_fix_incorrect_pointer_usage which fixes + incorrect pointer usage. + * debian/copyright: + + Update copyright years. + + [ Julien Danjou ] + * Switch to git based packaging + * Tweak get-orig-source + * Add autoconf as build dependency + * debian/control + + Bump standard version + + Add Vcs-* field + + -- Julien Danjou Thu, 12 Jun 2008 10:20:10 +0200 + +xcb-util (0.2-1) experimental; urgency=low + + * Initial release (Closes: #437681) + + -- Julien Danjou Tue, 25 Mar 2008 19:14:42 +0100 + diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100755 index 0000000..fdc5563 --- /dev/null +++ b/debian/control @@ -0,0 +1,344 @@ +Source: xcb-util +Section: libdevel +Priority: extra +Maintainer: Sung-Jin Park , Julien Danjou +Uploaders: SooChan Lim , Sung-Jin Park , Arnaud Fontaine +Build-Depends: cdbs, debhelper (>= 5), autotools-dev, libxcb-render0-dev, libxcb1-dev, gperf, pkg-config, libxcb-shm0-dev, m4, autoconf, automake, libtool, x11proto-core-dev (>= 7.0.12) +Standards-Version: 3.8.3 +Homepage: http://xcb.freedesktop.org +Vcs-Git: git://git.debian.org/git/collab-maint/xcb-util.git +Vcs-Browser: http://git.debian.org/?p=collab-maint/xcb-util.git + +Package: libxcb-atom1 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: utility libraries for X C Binding -- atom + This package contains the library files needed to run software using + libxcb-atom, providing standard core X atom constants and atom caching. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-atom1-dev +Conflicts: libxcb-atom0-dev +Replaces: libxcb-atom0-dev +Architecture: any +Depends: libxcb-atom1 (= ${binary:Version}), libxcb1-dev, ${misc:Depends} +Description: utility libraries for X C Binding -- atom + This package contains the header and library files needed to build software + using libxcb-atom, providing standard core X atom constants and atom caching. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-aux0 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: utility libraries for X C Binding -- aux + This package contains the library files needed to run software using + libxcb-aux, providing convenient access to connection setup and some + core requests. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-aux0-dev +Architecture: any +Depends: libxcb-aux0 (= ${binary:Version}), libxcb1-dev, ${misc:Depends} +Description: utility libraries for X C Binding -- aux + This package contains the header and library files needed to build software + using libxcb-aux, providing convenient access to connection setup and some + core requests. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-event1 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: utility libraries for X C Binding -- event + This package contains the library files needed to run software using + libxcb-event, providing X callback event handling. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-event1-dev +Conflicts: libxcb-event0-dev +Replaces: libxcb-event0-dev +Architecture: any +Depends: libxcb-event1 (= ${binary:Version}), libxcb1-dev, ${misc:Depends} +Description: utility libraries for X C Binding -- event + This package contains the header and library files needed to build software + using libxcb-event, providing X callback event handling. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-image0 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: utility libraries for X C Binding -- image + This package contains the library files needed to run software using + libxcb-image, providing port of Xlib's XImage and XShmImage functions. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-image0-dev +Architecture: any +Depends: libxcb-image0 (= ${binary:Version}), libxcb1-dev, libxcb-shm0-dev, ${misc:Depends} +Description: utility libraries for X C Binding -- image + This package contains the header and library files needed to build software + using libxcb-image, providing port of Xlib's XImage and XShmImage functions. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-keysyms1 +Conflicts: libxcb-keysyms0 +Replaces: libxcb-keysyms0 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: utility libraries for X C Binding -- keysyms + This package contains the library files needed to run software using + libxcb-keysyms, providing standard X key constants and conversion to/from + keycodes. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-keysyms1-dev +Conflicts: libxcb-keysyms0-dev +Replaces: libxcb-keysyms0-dev +Architecture: any +Depends: libxcb-keysyms1 (= ${binary:Version}), libxcb1-dev, ${misc:Depends} +Description: utility libraries for X C Binding -- keysyms + This package contains the header and library files needed to build software + using libxcb-keysyms, providing standard X key constants and conversion to/from + keycodes. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-property1 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: utility libraries for X C Binding -- property + This package contains the library files needed to run software using + libxcb-property, providing callback X property-change handling. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-property1-dev +Conflicts: libxcb-property0-dev +Replaces: libxcb-property0-dev +Architecture: any +Depends: libxcb-property1 (= ${binary:Version}), libxcb1-dev, libxcb-event1-dev, ${misc:Depends} +Description: utility libraries for X C Binding -- property + This package contains the header and library files needed to build software + using libxcb-property, providing callback X property-change handling. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-render-util0 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: utility libraries for X C Binding -- render-util + This package contains the library files needed to run software using + libxcb-render-util, providing convenience functions for the Render extension. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-render-util0-dev +Architecture: any +Depends: libxcb-render-util0 (= ${binary:Version}), libxcb1-dev, libxcb-render0-dev, ${misc:Depends} +Description: utility libraries for X C Binding -- render-util + This package contains the header and library files needed to build software + using libxcb-render-util, providing convenience functions for the Render + extension. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-reply1 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: utility libraries for X C Binding -- reply + This package contains the library files needed to run software using + libxcb-reply. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-reply1-dev +Conflicts: libxcb-reply0-dev +Replaces: libxcb-reply0-dev +Architecture: any +Depends: libxcb-reply1 (= ${binary:Version}), libxcb1-dev, ${misc:Depends} +Description: utility libraries for X C Binding -- reply + This package contains the header and library files needed to build software + using libxcb-reply. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-icccm1 +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: utility libraries for X C Binding -- icccm + This package contains the library files needed to run software using + libxcb-icccm, providing client and window-manager helpers for ICCCM. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-icccm1-dev +Conflicts: libxcb-icccm0-dev +Replaces: libxcb-icccm0-dev +Architecture: any +Depends: libxcb-icccm1 (= ${binary:Version}), libxcb1-dev, libxcb-atom1-dev, libxcb-property1-dev, ${misc:Depends} +Description: utility libraries for X C Binding -- icccm + This package contains the header and library files needed to build software + using libxcb-icccm, providing client and window-manager helpers for ICCCM. + . + The xcb-util module provides a number of libraries which sit on top of + libxcb, the core X protocol library, and some of the extension + libraries. These experimental libraries provide convenience functions + and interfaces which make the raw X protocol more usable. Some of the + libraries also provide client-side code which is not strictly part of + the X protocol but which have traditionally been provided by Xlib. + +Package: libxcb-atom1-dbg +Section: debug +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libxcb-atom1 (=${Source-Version}) +Description: Debug package of libxcb-atom1 + +Package: libxcb-aux0-dbg +Section: debug +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libxcb-aux0 (=${Source-Version}) +Description: Debug package of libxcb-aux0 + +Package: libxcb-event1-dbg +Section: debug +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libxcb-event1 (=${Source-Version}) +Description: Debug package of libxcb-event1 + +Package: libxcb-image0-dbg +Section: debug +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libxcb-image0 (=${Source-Version}) +Description: Debug package of libxcb-image0 + +Package: libxcb-keysyms1-dbg +Section: debug +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libxcb-keysyms1 (=${Source-Version}) +Description: Debug package of libxcb-keysyms1 + +Package: libxcb-property1-dbg +Section: debug +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libxcb-property1 (=${Source-Version}) +Description: Debug package of libxcb-property1 + +Package: libxcb-render-util0-dbg +Section: debug +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libxcb-render-util0 (=${Source-Version}) +Description: Debug package of libxcb-render-util0 + +Package: libxcb-reply1-dbg +Section: debug +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libxcb-reply1 (=${Source-Version}) +Description: Debug package of libxcb-reply1 + +Package: libxcb-icccm1-dbg +Section: debug +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libxcb-icccm1 (=${Source-Version}) +Description: Debug package of libxcb-icccm1 diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..44efd0c --- /dev/null +++ b/debian/copyright @@ -0,0 +1,45 @@ +This package was debianized by Julien Danjou on +Tue, 25 Mar 2008 19:14:42 +0100. + +It was downloaded from + +Upstream Authors: Bart Massey, Jamey Sharp, and Josh Triplett. + +Copyright: + + Copyright © 2006 Ian Osgood + Copyright © 2001-2008 Bart Massey, Jamey Sharp, and Josh Triplett. + Copyright © 2000 Keith Packard + +License: + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated + documentation files (the "Software"), to deal in the + Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, + sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall + be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the authors + or their institutions shall not be used in advertising or + otherwise to promote the sale, use or other dealings in this + Software without prior written authorization from the + authors. + +The Debian packaging is (C) 2008, Julien Danjou and +is licensed under the GPL, see `/usr/share/common-licenses/GPL-2'. diff --git a/debian/docs b/debian/docs new file mode 100644 index 0000000..e845566 --- /dev/null +++ b/debian/docs @@ -0,0 +1 @@ +README diff --git a/debian/libxcb-atom1-dev.install b/debian/libxcb-atom1-dev.install new file mode 100644 index 0000000..9380fd1 --- /dev/null +++ b/debian/libxcb-atom1-dev.install @@ -0,0 +1,4 @@ +usr/include/xcb/xcb_atom.h +usr/lib/libxcb-atom.a +usr/lib/libxcb-atom.so +usr/lib/pkgconfig/xcb-atom.pc diff --git a/debian/libxcb-atom1.install b/debian/libxcb-atom1.install new file mode 100644 index 0000000..8e05306 --- /dev/null +++ b/debian/libxcb-atom1.install @@ -0,0 +1 @@ +usr/lib/libxcb-atom.so.* diff --git a/debian/libxcb-aux0-dev.install b/debian/libxcb-aux0-dev.install new file mode 100644 index 0000000..3812ac0 --- /dev/null +++ b/debian/libxcb-aux0-dev.install @@ -0,0 +1,4 @@ +usr/include/xcb/xcb_aux.h +usr/lib/libxcb-aux.a +usr/lib/libxcb-aux.so +usr/lib/pkgconfig/xcb-aux.pc diff --git a/debian/libxcb-aux0.install b/debian/libxcb-aux0.install new file mode 100644 index 0000000..4d1494f --- /dev/null +++ b/debian/libxcb-aux0.install @@ -0,0 +1 @@ +usr/lib/libxcb-aux.so.* diff --git a/debian/libxcb-event1-dev.install b/debian/libxcb-event1-dev.install new file mode 100644 index 0000000..eaaf9ae --- /dev/null +++ b/debian/libxcb-event1-dev.install @@ -0,0 +1,4 @@ +usr/include/xcb/xcb_event.h +usr/lib/libxcb-event.a +usr/lib/libxcb-event.so +usr/lib/pkgconfig/xcb-event.pc diff --git a/debian/libxcb-event1.install b/debian/libxcb-event1.install new file mode 100644 index 0000000..e276328 --- /dev/null +++ b/debian/libxcb-event1.install @@ -0,0 +1 @@ +usr/lib/libxcb-event.so.* diff --git a/debian/libxcb-icccm1-dev.install b/debian/libxcb-icccm1-dev.install new file mode 100644 index 0000000..66836a6 --- /dev/null +++ b/debian/libxcb-icccm1-dev.install @@ -0,0 +1,4 @@ +usr/include/xcb/xcb_icccm.h +usr/lib/libxcb-icccm.a +usr/lib/libxcb-icccm.so +usr/lib/pkgconfig/xcb-icccm.pc diff --git a/debian/libxcb-icccm1.install b/debian/libxcb-icccm1.install new file mode 100644 index 0000000..4495ef2 --- /dev/null +++ b/debian/libxcb-icccm1.install @@ -0,0 +1 @@ +usr/lib/libxcb-icccm.so.* diff --git a/debian/libxcb-image0-dev.install b/debian/libxcb-image0-dev.install new file mode 100644 index 0000000..44a9709 --- /dev/null +++ b/debian/libxcb-image0-dev.install @@ -0,0 +1,4 @@ +usr/include/xcb/xcb_image.h +usr/lib/libxcb-image.a +usr/lib/libxcb-image.so +usr/lib/pkgconfig/xcb-image.pc diff --git a/debian/libxcb-image0.install b/debian/libxcb-image0.install new file mode 100644 index 0000000..16032e2 --- /dev/null +++ b/debian/libxcb-image0.install @@ -0,0 +1 @@ +usr/lib/libxcb-image.so.* diff --git a/debian/libxcb-keysyms1-dev.install b/debian/libxcb-keysyms1-dev.install new file mode 100644 index 0000000..f653b2b --- /dev/null +++ b/debian/libxcb-keysyms1-dev.install @@ -0,0 +1,4 @@ +usr/include/xcb/xcb_keysyms.h +usr/lib/libxcb-keysyms.a +usr/lib/libxcb-keysyms.so +usr/lib/pkgconfig/xcb-keysyms.pc diff --git a/debian/libxcb-keysyms1.install b/debian/libxcb-keysyms1.install new file mode 100644 index 0000000..c9f9aaf --- /dev/null +++ b/debian/libxcb-keysyms1.install @@ -0,0 +1 @@ +usr/lib/libxcb-keysyms.so.* diff --git a/debian/libxcb-property1-dev.install b/debian/libxcb-property1-dev.install new file mode 100644 index 0000000..c92e8df --- /dev/null +++ b/debian/libxcb-property1-dev.install @@ -0,0 +1,4 @@ +usr/include/xcb/xcb_property.h +usr/lib/libxcb-property.a +usr/lib/libxcb-property.so +usr/lib/pkgconfig/xcb-property.pc diff --git a/debian/libxcb-property1.install b/debian/libxcb-property1.install new file mode 100644 index 0000000..ed97345 --- /dev/null +++ b/debian/libxcb-property1.install @@ -0,0 +1 @@ +usr/lib/libxcb-property.so.* diff --git a/debian/libxcb-render-util0-dev.install b/debian/libxcb-render-util0-dev.install new file mode 100644 index 0000000..730e5ac --- /dev/null +++ b/debian/libxcb-render-util0-dev.install @@ -0,0 +1,4 @@ +usr/include/xcb/xcb_renderutil.h +usr/lib/libxcb-render-util.a +usr/lib/libxcb-render-util.so +usr/lib/pkgconfig/xcb-renderutil.pc diff --git a/debian/libxcb-render-util0.install b/debian/libxcb-render-util0.install new file mode 100644 index 0000000..0ee0d82 --- /dev/null +++ b/debian/libxcb-render-util0.install @@ -0,0 +1 @@ +usr/lib/libxcb-render-util.so.* diff --git a/debian/libxcb-reply1-dev.install b/debian/libxcb-reply1-dev.install new file mode 100644 index 0000000..ea0a634 --- /dev/null +++ b/debian/libxcb-reply1-dev.install @@ -0,0 +1,4 @@ +usr/include/xcb/xcb_reply.h +usr/lib/libxcb-reply.a +usr/lib/libxcb-reply.so +usr/lib/pkgconfig/xcb-reply.pc diff --git a/debian/libxcb-reply1.install b/debian/libxcb-reply1.install new file mode 100644 index 0000000..edbdf19 --- /dev/null +++ b/debian/libxcb-reply1.install @@ -0,0 +1 @@ +usr/lib/libxcb-reply.so.* diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..4f857cb --- /dev/null +++ b/debian/rules @@ -0,0 +1,25 @@ +#!/usr/bin/make -f + +DEB_DH_INSTALL_SOURCEDIR=debian/tmp + +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/class/autotools.mk + +DEB_DH_MAKESHLIBS_ARGS=-V +DEB_DBG_PACKAGES="libxcb-atom1-dbg libxcb-aux0-dbg libxcb-event1-dbg libxcb-image0-dbg libxcb-keysyms1-dbg libxcb-property1-dbg libxcb-render-util0-dbg libxcb-reply1-dbg libxcb-icccm1-dbg" + +ORIG_MAJOR=$(shell git describe upstream | cut -d- -f1) +ORIG_GIT=$(shell git describe upstream | cut -d- -f2) + +LDFLAGS += -Wl,--hash-style=both -Wl,--as-needed + +post-patches:: configure-stamp +configure-stamp: + sh ./autogen.sh $(DEB_CONFIGURE_NORMAL_ARGS) + touch configure-stamp + +cleanbuilddir:: + rm -f configure-stamp + +get-orig-source: + git archive upstream | gzip -9 > ../xcb-util_$(ORIG_MAJOR)+git$(ORIG_GIT).orig.tar.gz diff --git a/debian/watch b/debian/watch new file mode 100644 index 0000000..71f8cfe --- /dev/null +++ b/debian/watch @@ -0,0 +1,2 @@ +version=3 +http://xcb.freedesktop.org/dist/xcb-util-(.*)\.tar\.gz diff --git a/depcomp b/depcomp new file mode 100755 index 0000000..df8eea7 --- /dev/null +++ b/depcomp @@ -0,0 +1,630 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free +# Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u="sed s,\\\\\\\\,/,g" + depmode=msvisualcpp +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/event/Makefile.am b/event/Makefile.am new file mode 100644 index 0000000..5a7d819 --- /dev/null +++ b/event/Makefile.am @@ -0,0 +1,17 @@ + +MAINTAINERCLEANFILES = Makefile.in + +lib_LTLIBRARIES = libxcb-event.la + +xcbinclude_HEADERS = xcb_event.h + +AM_CFLAGS = $(CWARNFLAGS) + +libxcb_event_la_SOURCES = event.c +libxcb_event_la_CPPFLAGS = $(XCB_CFLAGS) +libxcb_event_la_LIBADD = $(XCB_LIBS) +libxcb_event_la_LDFLAGS = -version-info 1:0:0 + +pkgconfig_DATA = xcb-event.pc + +EXTRA_DIST = xcb-event.pc.in diff --git a/event/event.c b/event/event.c new file mode 100644 index 0000000..7faac1c --- /dev/null +++ b/event/event.c @@ -0,0 +1,337 @@ +/* + * Copyright © 2008-2009 Julien Danjou + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +#include +#include +#include + +#include "xcb_event.h" +#include "../xcb-util-common.h" + +void +xcb_event_handlers_init(xcb_connection_t *c, xcb_event_handlers_t *evenths) +{ + memset(evenths, 0, sizeof(xcb_event_handlers_t)); + evenths->c = c; +} + +xcb_connection_t * +xcb_event_get_xcb_connection(xcb_event_handlers_t *evenths) +{ + return evenths->c; +} + +static xcb_event_handler_t * +get_event_handler(xcb_event_handlers_t *evenths, int event) +{ + assert(event < 256); + event &= XCB_EVENT_RESPONSE_TYPE_MASK; + assert(event >= 2); + return &evenths->event[event - 2]; +} + +static xcb_event_handler_t * +get_error_handler(xcb_event_handlers_t *evenths, int error) +{ + assert(error >= 0 && error < 256); + return &evenths->error[error]; +} + +int +xcb_event_handle(xcb_event_handlers_t *evenths, xcb_generic_event_t *event) +{ + xcb_event_handler_t *eventh = 0; + assert(event->response_type != 1); + + if(event->response_type == 0) + eventh = get_error_handler(evenths, ((xcb_generic_error_t *) event)->error_code); + else + eventh = get_event_handler(evenths, event->response_type); + + if(eventh->handler) + return eventh->handler(eventh->data, evenths->c, event); + return 0; +} + +void +xcb_event_wait_for_event_loop(xcb_event_handlers_t *evenths) +{ + xcb_generic_event_t *event; + while((event = xcb_wait_for_event(evenths->c))) + { + xcb_event_handle(evenths, event); + free(event); + } +} + +void +xcb_event_poll_for_event_loop(xcb_event_handlers_t *evenths) +{ + xcb_generic_event_t *event; + while ((event = xcb_poll_for_event(evenths->c))) + { + xcb_event_handle(evenths, event); + free(event); + } +} + +static void +set_handler(xcb_generic_event_handler_t handler, void *data, xcb_event_handler_t *place) +{ + xcb_event_handler_t eventh = { handler, data }; + *place = eventh; +} + +void +xcb_event_set_handler(xcb_event_handlers_t *evenths, int event, xcb_generic_event_handler_t handler, void *data) +{ + set_handler(handler, data, get_event_handler(evenths, event)); +} + +void +xcb_event_set_error_handler(xcb_event_handlers_t *evenths, int error, xcb_generic_error_handler_t handler, void *data) +{ + set_handler((xcb_generic_event_handler_t) handler, data, get_error_handler(evenths, error)); +} + +static const char *labelError[] = +{ + "Success", + "BadRequest", + "BadValue", + "BadWindow", + "BadPixmap", + "BadAtom", + "BadCursor", + "BadFont", + "BadMatch", + "BadDrawable", + "BadAccess", + "BadAlloc", + "BadColor", + "BadGC", + "BadIDChoice", + "BadName", + "BadLength", + "BadImplementation", +}; + +static const char *labelRequest[] = +{ + "no request", + "CreateWindow", + "ChangeWindowAttributes", + "GetWindowAttributes", + "DestroyWindow", + "DestroySubwindows", + "ChangeSaveSet", + "ReparentWindow", + "MapWindow", + "MapSubwindows", + "UnmapWindow", + "UnmapSubwindows", + "ConfigureWindow", + "CirculateWindow", + "GetGeometry", + "QueryTree", + "InternAtom", + "GetAtomName", + "ChangeProperty", + "DeleteProperty", + "GetProperty", + "ListProperties", + "SetSelectionOwner", + "GetSelectionOwner", + "ConvertSelection", + "SendEvent", + "GrabPointer", + "UngrabPointer", + "GrabButton", + "UngrabButton", + "ChangeActivePointerGrab", + "GrabKeyboard", + "UngrabKeyboard", + "GrabKey", + "UngrabKey", + "AllowEvents", + "GrabServer", + "UngrabServer", + "QueryPointer", + "GetMotionEvents", + "TranslateCoords", + "WarpPointer", + "SetInputFocus", + "GetInputFocus", + "QueryKeymap", + "OpenFont", + "CloseFont", + "QueryFont", + "QueryTextExtents", + "ListFonts", + "ListFontsWithInfo", + "SetFontPath", + "GetFontPath", + "CreatePixmap", + "FreePixmap", + "CreateGC", + "ChangeGC", + "CopyGC", + "SetDashes", + "SetClipRectangles", + "FreeGC", + "ClearArea", + "CopyArea", + "CopyPlane", + "PolyPoint", + "PolyLine", + "PolySegment", + "PolyRectangle", + "PolyArc", + "FillPoly", + "PolyFillRectangle", + "PolyFillArc", + "PutImage", + "GetImage", + "PolyText", + "PolyText", + "ImageText", + "ImageText", + "CreateColormap", + "FreeColormap", + "CopyColormapAndFree", + "InstallColormap", + "UninstallColormap", + "ListInstalledColormaps", + "AllocColor", + "AllocNamedColor", + "AllocColorCells", + "AllocColorPlanes", + "FreeColors", + "StoreColors", + "StoreNamedColor", + "QueryColors", + "LookupColor", + "CreateCursor", + "CreateGlyphCursor", + "FreeCursor", + "RecolorCursor", + "QueryBestSize", + "QueryExtension", + "ListExtensions", + "ChangeKeyboardMapping", + "GetKeyboardMapping", + "ChangeKeyboardControl", + "GetKeyboardControl", + "Bell", + "ChangePointerControl", + "GetPointerControl", + "SetScreenSaver", + "GetScreenSaver", + "ChangeHosts", + "ListHosts", + "SetAccessControl", + "SetCloseDownMode", + "KillClient", + "RotateProperties", + "ForceScreenSaver", + "SetPointerMapping", + "GetPointerMapping", + "SetModifierMapping", + "GetModifierMapping", + "major 120", + "major 121", + "major 122", + "major 123", + "major 124", + "major 125", + "major 126", + "NoOperation", +}; + +static const char *labelEvent[] = +{ + "error", + "reply", + "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", +}; + +const char * +xcb_event_get_label(uint8_t type) +{ + if(type < countof(labelEvent)) + return labelEvent[type]; + return NULL; +} + +const char * +xcb_event_get_error_label(uint8_t type) +{ + if(type < countof(labelError)) + return labelError[type]; + return NULL; +} + +const char * +xcb_event_get_request_label(uint8_t type) +{ + if(type < countof(labelRequest)) + return labelRequest[type]; + return NULL; +} diff --git a/event/xcb-event.pc.in b/event/xcb-event.pc.in new file mode 100644 index 0000000..535607e --- /dev/null +++ b/event/xcb-event.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: XCB Event library +Description: XCB event callback interface +Version: @PACKAGE_VERSION@ +Requires: xcb +Libs: -L${libdir} -lxcb-event @LIBS@ +Cflags: -I${includedir} diff --git a/event/xcb_event.h b/event/xcb_event.h new file mode 100644 index 0000000..9bd286b --- /dev/null +++ b/event/xcb_event.h @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2008-2009 Julien Danjou + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +/** + * @defgroup xcb__event_t XCB Event Functions + * + * These functions ease the handling of X events received. + * + * @{ + */ + +#ifndef __XCB_EVENT_H__ +#define __XCB_EVENT_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Bit mask to find event type regardless of event source. + * + * Each event in the X11 protocol contains an 8-bit type code. + * The most-significant bit in this code is set if the event was + * generated from a SendEvent request. This mask can be used to + * determine the type of event regardless of how the event was + * generated. See the X11R6 protocol specification for details. + */ +#define XCB_EVENT_RESPONSE_TYPE_MASK (0x7f) +#define XCB_EVENT_RESPONSE_TYPE(e) (e->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) +#define XCB_EVENT_SENT(e) (e->response_type & ~XCB_EVENT_RESPONSE_TYPE_MASK) + +typedef int (*xcb_generic_event_handler_t)(void *data, xcb_connection_t *c, xcb_generic_event_t *event); +typedef int (*xcb_generic_error_handler_t)(void *data, xcb_connection_t *c, xcb_generic_error_t *error); + +typedef struct xcb_event_handler xcb_event_handler_t; +struct xcb_event_handler +{ + xcb_generic_event_handler_t handler; + void *data; +}; + +typedef struct xcb_event_handlers xcb_event_handlers_t; +struct xcb_event_handlers +{ + xcb_event_handler_t event[126]; + xcb_event_handler_t error[256]; + xcb_connection_t *c; +}; + +/** + * @brief Initialize event handlers data structure. + * @param c The connection to the X server. + * @param evenths A pointer to the event handler data structure to initialize. + */ +void xcb_event_handlers_init(xcb_connection_t *c, xcb_event_handlers_t *evenths); + +/** + * @brief Get X connection used in event handlers. + * @param evenths The event handlers. + * @return The connection to the X server. + */ +xcb_connection_t *xcb_event_get_xcb_connection(xcb_event_handlers_t *evenths); + +/** + * @brief Wait for event and handle it with event handler. + * @param evenths The event handlers. + */ +void xcb_event_wait_for_event_loop(xcb_event_handlers_t *evenths); + +/** + * @brief Poll for event and handle it with event handler. + * @param evenths The event handlers. + */ +void xcb_event_poll_for_event_loop(xcb_event_handlers_t *evenths); + +/** + * @brief Handle an event using event handlers from event handlers data + * structure. + * @param evenths The event handlers. + * @param event The event to handle. + * @return The return value of the handler, or 0 if no handler exists for this + * event. + */ +int xcb_event_handle(xcb_event_handlers_t *evenths, xcb_generic_event_t *event); + +/** + * @brief Set an event handler for an event type. + * @param evenths The event handlers data structure. + * @param event The event type. + * @param handler The callback function to call for this event type. + * @param data Optional data pointer to pass to handler callback function. + */ +void xcb_event_set_handler(xcb_event_handlers_t *evenths, int event, xcb_generic_event_handler_t handler, void *data); + +/** + * @brief Set an error handler for an error type. + * @param evenths The error handlers data structure. + * @param error The error type. + * @param handler The callback function to call for this error type. + * @param data Optional data pointer to pass to handler callback function. + */ +void xcb_event_set_error_handler(xcb_event_handlers_t *evenths, int error, xcb_generic_error_handler_t handler, void *data); + +#define XCB_EVENT_MAKE_EVENT_HANDLER(lkind, ukind) \ +static inline void xcb_event_set_##lkind##_handler(xcb_event_handlers_t *evenths, int (*handler)(void *, xcb_connection_t *, xcb_##lkind##_event_t *), void *data) \ +{ \ + xcb_event_set_handler(evenths, XCB_##ukind, (xcb_generic_event_handler_t) handler, data); \ +} + +XCB_EVENT_MAKE_EVENT_HANDLER(key_press, KEY_PRESS) +XCB_EVENT_MAKE_EVENT_HANDLER(key_release, KEY_RELEASE) +XCB_EVENT_MAKE_EVENT_HANDLER(button_press, BUTTON_PRESS) +XCB_EVENT_MAKE_EVENT_HANDLER(button_release, BUTTON_RELEASE) +XCB_EVENT_MAKE_EVENT_HANDLER(motion_notify, MOTION_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(enter_notify, ENTER_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(leave_notify, LEAVE_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(focus_in, FOCUS_IN) +XCB_EVENT_MAKE_EVENT_HANDLER(focus_out, FOCUS_OUT) +XCB_EVENT_MAKE_EVENT_HANDLER(keymap_notify, KEYMAP_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(expose, EXPOSE) +XCB_EVENT_MAKE_EVENT_HANDLER(graphics_exposure, GRAPHICS_EXPOSURE) +XCB_EVENT_MAKE_EVENT_HANDLER(no_exposure, NO_EXPOSURE) +XCB_EVENT_MAKE_EVENT_HANDLER(visibility_notify, VISIBILITY_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(create_notify, CREATE_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(destroy_notify, DESTROY_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(unmap_notify, UNMAP_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(map_notify, MAP_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(map_request, MAP_REQUEST) +XCB_EVENT_MAKE_EVENT_HANDLER(reparent_notify, REPARENT_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(configure_notify, CONFIGURE_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(configure_request, CONFIGURE_REQUEST) +XCB_EVENT_MAKE_EVENT_HANDLER(gravity_notify, GRAVITY_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(resize_request, RESIZE_REQUEST) +XCB_EVENT_MAKE_EVENT_HANDLER(circulate_notify, CIRCULATE_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(circulate_request, CIRCULATE_REQUEST) +XCB_EVENT_MAKE_EVENT_HANDLER(property_notify, PROPERTY_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(selection_clear, SELECTION_CLEAR) +XCB_EVENT_MAKE_EVENT_HANDLER(selection_request, SELECTION_REQUEST) +XCB_EVENT_MAKE_EVENT_HANDLER(selection_notify, SELECTION_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(colormap_notify, COLORMAP_NOTIFY) +XCB_EVENT_MAKE_EVENT_HANDLER(client_message, CLIENT_MESSAGE) +XCB_EVENT_MAKE_EVENT_HANDLER(mapping_notify, MAPPING_NOTIFY) + +/** Everyting is ok */ +#define XCB_EVENT_ERROR_SUCESS 0 +/** Bad request code */ +#define XCB_EVENT_ERROR_BAD_REQUEST 1 +/** Int parameter out of range */ +#define XCB_EVENT_ERROR_BAD_VALUE 2 +/** Parameter not a Window */ +#define XCB_EVENT_ERROR_BAD_WINDOW 3 +/** Parameter not a Pixmap */ +#define XCB_EVENT_ERROR_BAD_PIXMAP 4 +/** Parameter not an Atom */ +#define XCB_EVENT_ERROR_BAD_ATOM 5 +/** Parameter not a Cursor */ +#define XCB_EVENT_ERROR_BAD_CURSOR 6 +/** Parameter not a Font */ +#define XCB_EVENT_ERROR_BAD_FONT 7 +/** Parameter mismatch */ +#define XCB_EVENT_ERROR_BAD_MATCH 8 +/** Parameter not a Pixmap or Window */ +#define XCB_EVENT_ERROR_BAD_DRAWABLE 9 +/* Depending on context: + - key/button already grabbed + - attempt to free an illegal + cmap entry + - attempt to store into a read-only + color map entry. + - attempt to modify the access control + list from other than the local host. +*/ +#define XCB_EVENT_ERROR_BAD_ACCESS 10 +/** Insufficient resources */ +#define XCB_EVENT_ERROR_BAD_ALLOC 11 +/** No such colormap */ +#define XCB_EVENT_ERROR_BAD_COLOR 12 +/** Parameter not a GC */ +#define XCB_EVENT_ERROR_BAD_GC 13 +/** Choice not in range or already used */ +#define XCB_EVENT_ERROR_BAD_ID_CHOICE 14 +/** Font or color name doesn't exist */ +#define XCB_EVENT_ERROR_BAD_NAME 15 +/** Request length incorrect */ +#define XCB_EVENT_ERROR_BAD_LENGTH 16 +/** Server is defective */ +#define XCB_EVENT_ERROR_BAD_IMPLEMENTATION 17 + +/** + * @brief Convert an event reponse type to a label. + * @param type The event type. + * @return A string with the event name, or NULL if unknown. + */ +const char * xcb_event_get_label(uint8_t type); + +/** + * @brief Convert an event error type to a label. + * @param type The erro type. + * @return A string with the event name, or NULL if unknown or if the event is + * not an error. + */ +const char * xcb_event_get_error_label(uint8_t type); + +/** + * @brief Convert an event request type to a label. + * @param type The request type. + * @return A string with the event name, or NULL if unknown or if the event is + * not an error. + */ +const char * xcb_event_get_request_label(uint8_t type); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __XCB_EVENT_H__ */ diff --git a/gendoc b/gendoc new file mode 100644 index 0000000..7b53f45 --- /dev/null +++ b/gendoc @@ -0,0 +1,7 @@ +#!/bin/sh +rm -rf ./doc/html ./doc/latex ./doc/man +doxygen +rm -f xcb_util_docs.tar xcb_util_docs.tar.gz +tar -cvf xcb_util_docs.tar doc/html doc/man doc/latex doc/xml +gzip -9 xcb_util_docs.tar +exit 0 diff --git a/icccm/Makefile.am b/icccm/Makefile.am new file mode 100644 index 0000000..9ad4238 --- /dev/null +++ b/icccm/Makefile.am @@ -0,0 +1,18 @@ + +MAINTAINERCLEANFILES = Makefile.in + +lib_LTLIBRARIES = libxcb-icccm.la + +xcbinclude_HEADERS = xcb_icccm.h + +AM_CFLAGS = $(CWARNFLAGS) + +libxcb_icccm_la_SOURCES = icccm.c +libxcb_icccm_la_CPPFLAGS = $(XCB_CFLAGS) $(XCB_ATOM_CFLAGS) $(XCB_EVENT_CFLAGS) \ + $(XCB_PROPERTY_CFLAGS) +libxcb_icccm_la_LIBADD = $(XCB_LIBS) $(XCB_ATOM_LIBS) $(XCB_PROPERTY_LIBS) +libxcb_icccm_la_LDFLAGS = -version-info 1:0:0 + +pkgconfig_DATA = xcb-icccm.pc + +EXTRA_DIST = xcb-icccm.pc.in diff --git a/icccm/icccm.c b/icccm/icccm.c new file mode 100644 index 0000000..776c299 --- /dev/null +++ b/icccm/icccm.c @@ -0,0 +1,726 @@ +/* + * Copyright © 2008 Arnaud Fontaine + * Copyright © 2007-2008 Vincent Torri + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +#include +#include +#include + +#include "xcb_icccm.h" +#include "xcb_atom.h" + +xcb_get_property_cookie_t +xcb_get_text_property(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t property) +{ + return xcb_get_any_property(c, 0, window, property, UINT_MAX); +} + +xcb_get_property_cookie_t +xcb_get_text_property_unchecked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t property) +{ + return xcb_get_any_property_unchecked(c, 0, window, property, UINT_MAX); +} + +uint8_t +xcb_get_text_property_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_get_text_property_reply_t *prop, + xcb_generic_error_t **e) +{ + xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); + + if(!reply) + return 0; + + prop->_reply = reply; + prop->encoding = prop->_reply->type; + prop->format = prop->_reply->format; + prop->name_len = xcb_get_property_value_length(prop->_reply); + prop->name = xcb_get_property_value(prop->_reply); + + return 1; +} + +void +xcb_get_text_property_reply_wipe(xcb_get_text_property_reply_t *prop) +{ + free(prop->_reply); +} + +/* WM_NAME */ + +void +xcb_set_wm_name_checked(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t encoding, uint32_t name_len, + const char *name) +{ + xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, WM_NAME, + encoding, 8, name_len, name); +} + +void +xcb_set_wm_name(xcb_connection_t *c, xcb_window_t window, xcb_atom_t encoding, + uint32_t name_len, const char *name) +{ + xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, WM_NAME, encoding, 8, + name_len, name); +} + +xcb_get_property_cookie_t +xcb_get_wm_name(xcb_connection_t *c, + xcb_window_t window) +{ + return xcb_get_text_property(c, window, WM_NAME); +} + +xcb_get_property_cookie_t +xcb_get_wm_name_unchecked(xcb_connection_t *c, + xcb_window_t window) +{ + return xcb_get_text_property_unchecked(c, window, WM_NAME); +} + +uint8_t +xcb_get_wm_name_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_get_text_property_reply_t *prop, + xcb_generic_error_t **e) +{ + return xcb_get_text_property_reply(c, cookie, prop, e); +} + +void +xcb_watch_wm_name(xcb_property_handlers_t *prophs, uint32_t long_len, + xcb_generic_property_handler_t handler, void *data) +{ + xcb_property_set_handler(prophs, WM_NAME, long_len, handler, data); +} + +/* WM_ICON_NAME */ + +void +xcb_set_wm_icon_name_checked(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t encoding, uint32_t name_len, + const char *name) +{ + xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, WM_ICON_NAME, + encoding, 8, name_len, name); +} + +void +xcb_set_wm_icon_name(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t encoding, uint32_t name_len, const char *name) +{ + xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, WM_ICON_NAME, encoding, + 8, name_len, name); +} + +xcb_get_property_cookie_t +xcb_get_wm_icon_name(xcb_connection_t *c, + xcb_window_t window) +{ + return xcb_get_text_property(c, window, WM_ICON_NAME); +} + +xcb_get_property_cookie_t +xcb_get_wm_icon_name_unchecked(xcb_connection_t *c, + xcb_window_t window) +{ + return xcb_get_text_property_unchecked(c, window, WM_ICON_NAME); +} + +uint8_t +xcb_get_wm_icon_name_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_get_text_property_reply_t *prop, + xcb_generic_error_t **e) +{ + return xcb_get_text_property_reply(c, cookie, prop, e); +} + +void +xcb_watch_wm_icon_name(xcb_property_handlers_t *prophs, uint32_t long_len, + xcb_generic_property_handler_t handler, void *data) +{ + xcb_property_set_handler(prophs, WM_ICON_NAME, long_len, handler, data); +} + +/* WM_CLIENT_MACHINE */ + +void +xcb_set_wm_client_machine_checked(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t encoding, uint32_t name_len, + const char *name) +{ + xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, + WM_CLIENT_MACHINE, encoding, 8, name_len, name); +} + +void +xcb_set_wm_client_machine(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t encoding, uint32_t name_len, + const char *name) +{ + xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, WM_CLIENT_MACHINE, + encoding, 8, name_len, name); +} + +xcb_get_property_cookie_t +xcb_get_wm_client_machine(xcb_connection_t *c, + xcb_window_t window) +{ + return xcb_get_text_property(c, window, WM_CLIENT_MACHINE); +} + +xcb_get_property_cookie_t +xcb_get_wm_client_machine_unchecked(xcb_connection_t *c, + xcb_window_t window) +{ + return xcb_get_text_property_unchecked(c, window, WM_CLIENT_MACHINE); +} + +uint8_t +xcb_get_wm_client_machine_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_get_text_property_reply_t *prop, + xcb_generic_error_t **e) +{ + return xcb_get_text_property_reply(c, cookie, prop, e); +} + +void +xcb_watch_wm_client_machine(xcb_property_handlers_t *prophs, uint32_t long_len, + xcb_generic_property_handler_t handler, void *data) +{ + xcb_property_set_handler(prophs, WM_CLIENT_MACHINE, long_len, handler, data); +} + +/* WM_CLASS */ + +xcb_get_property_cookie_t +xcb_get_wm_class(xcb_connection_t *c, xcb_window_t window) +{ + return xcb_get_property(c, 0, window, WM_CLASS, STRING, 0L, 2048L); +} + +xcb_get_property_cookie_t +xcb_get_wm_class_unchecked(xcb_connection_t *c, xcb_window_t window) +{ + return xcb_get_property_unchecked(c, 0, window, WM_CLASS, STRING, 0L, 2048L); +} + +uint8_t +xcb_get_wm_class_from_reply(xcb_get_wm_class_reply_t *prop, + xcb_get_property_reply_t *reply) +{ + if(!reply || reply->type != STRING || reply->format != 8) + return 0; + + prop->_reply = reply; + prop->instance_name = (char *) xcb_get_property_value(prop->_reply); + + int name_len = strlen(prop->instance_name); + if(name_len == xcb_get_property_value_length(prop->_reply)) + name_len--; + + prop->class_name = prop->instance_name + name_len + 1; + + return 1; +} + +uint8_t +xcb_get_wm_class_reply(xcb_connection_t *c, xcb_get_property_cookie_t cookie, + xcb_get_wm_class_reply_t *prop, xcb_generic_error_t **e) +{ + xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); + uint8_t ret = xcb_get_wm_class_from_reply(prop, reply); + /* if reply parsing failed, free the reply to avoid mem leak */ + if(!ret) + free(reply); + return ret; +} + +void +xcb_get_wm_class_reply_wipe(xcb_get_wm_class_reply_t *prop) +{ + free(prop->_reply); +} + +/* WM_TRANSIENT_FOR */ + +xcb_get_property_cookie_t +xcb_get_wm_transient_for(xcb_connection_t *c, xcb_window_t window) +{ + return xcb_get_property(c, 0, window, WM_TRANSIENT_FOR, WINDOW, 0, 1); +} + +xcb_get_property_cookie_t +xcb_get_wm_transient_for_unchecked(xcb_connection_t *c, xcb_window_t window) +{ + return xcb_get_property_unchecked(c, 0, window, WM_TRANSIENT_FOR, WINDOW, 0, 1); +} + +uint8_t +xcb_get_wm_transient_for_from_reply(xcb_window_t *prop, + xcb_get_property_reply_t *reply) +{ + if(!reply || reply->type != WINDOW || reply->format != 32 || !reply->length) + return 0; + + *prop = *((xcb_window_t *) xcb_get_property_value(reply)); + + return 1; +} + +uint8_t +xcb_get_wm_transient_for_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_window_t *prop, + xcb_generic_error_t **e) +{ + xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); + uint8_t ret = xcb_get_wm_transient_for_from_reply(prop, reply); + free(reply); + return ret; +} + +/* WM_SIZE_HINTS */ + +void +xcb_size_hints_set_position(xcb_size_hints_t *hints, int user_specified, + int32_t x, int32_t y) +{ + hints->flags &= ~(XCB_SIZE_HINT_US_POSITION | XCB_SIZE_HINT_P_POSITION); + if (user_specified) + hints->flags |= XCB_SIZE_HINT_US_POSITION; + else + hints->flags |= XCB_SIZE_HINT_P_POSITION; + hints->x = x; + hints->y = y; +} + +void +xcb_size_hints_set_size(xcb_size_hints_t *hints, int user_specified, + int32_t width, int32_t height) +{ + hints->flags &= ~(XCB_SIZE_HINT_US_SIZE | XCB_SIZE_HINT_P_SIZE); + if (user_specified) + hints->flags |= XCB_SIZE_HINT_US_SIZE; + else + hints->flags |= XCB_SIZE_HINT_P_SIZE; + hints->width = width; + hints->height = height; +} + +void +xcb_size_hints_set_min_size(xcb_size_hints_t *hints, int32_t min_width, + int32_t min_height) +{ + hints->flags |= XCB_SIZE_HINT_P_MIN_SIZE; + hints->min_width = min_width; + hints->min_height = min_height; +} + +void +xcb_size_hints_set_max_size(xcb_size_hints_t *hints, int32_t max_width, + int32_t max_height) +{ + hints->flags |= XCB_SIZE_HINT_P_MAX_SIZE; + hints->max_width = max_width; + hints->max_height = max_height; +} + +void +xcb_size_hints_set_resize_inc(xcb_size_hints_t *hints, int32_t width_inc, + int32_t height_inc) +{ + hints->flags |= XCB_SIZE_HINT_P_RESIZE_INC; + hints->width_inc = width_inc; + hints->height_inc = height_inc; +} + +void +xcb_size_hints_set_aspect(xcb_size_hints_t *hints, int32_t min_aspect_num, + int32_t min_aspect_den, int32_t max_aspect_num, + int32_t max_aspect_den) +{ + hints->flags |= XCB_SIZE_HINT_P_ASPECT; + hints->min_aspect_num = min_aspect_num; + hints->min_aspect_den = min_aspect_den; + hints->max_aspect_num = max_aspect_num; + hints->max_aspect_den = max_aspect_den; +} + +void +xcb_size_hints_set_base_size(xcb_size_hints_t *hints, int32_t base_width, + int32_t base_height) +{ + hints->flags |= XCB_SIZE_HINT_BASE_SIZE; + hints->base_width = base_width; + hints->base_height = base_height; +} + +void +xcb_size_hints_set_win_gravity(xcb_size_hints_t *hints, xcb_gravity_t win_gravity) +{ + hints->flags |= XCB_SIZE_HINT_P_WIN_GRAVITY; + hints->win_gravity = win_gravity; +} + +void +xcb_set_wm_size_hints_checked(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t property, xcb_size_hints_t *hints) +{ + xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, property, + WM_SIZE_HINTS, 32, sizeof(*hints) >> 2, hints); +} + +void +xcb_set_wm_size_hints(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t property, xcb_size_hints_t *hints) +{ + xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, property, + WM_SIZE_HINTS, 32, sizeof(*hints) >> 2, hints); +} + +xcb_get_property_cookie_t +xcb_get_wm_size_hints(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t property) +{ + /* NumPropSizeElements = 18 (ICCCM version 1). */ + return xcb_get_property(c, 0, window, property, WM_SIZE_HINTS, 0L, 18); +} + +xcb_get_property_cookie_t +xcb_get_wm_size_hints_unchecked(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t property) +{ + return xcb_get_property_unchecked(c, 0, window, property, WM_SIZE_HINTS, + 0L, 18); +} + +uint8_t +xcb_get_wm_size_hints_from_reply(xcb_size_hints_t *hints, xcb_get_property_reply_t *reply) +{ + uint32_t flags; + + if(!reply) + return 0; + + int length = xcb_get_property_value_length(reply) / (reply->format / 8); + + if (!(reply->type == WM_SIZE_HINTS && + (reply->format == 8 || reply->format == 16 || + reply->format == 32) && + /* OldNumPropSizeElements = 15 (pre-ICCCM) */ + length >= 15)) + return 0; + + memcpy(hints, (xcb_size_hints_t *) xcb_get_property_value (reply), + length * reply->format >> 3); + + flags = (XCB_SIZE_HINT_US_POSITION | XCB_SIZE_HINT_US_SIZE | + XCB_SIZE_HINT_P_POSITION | XCB_SIZE_HINT_P_SIZE | + XCB_SIZE_HINT_P_MIN_SIZE | XCB_SIZE_HINT_P_MAX_SIZE | + XCB_SIZE_HINT_P_RESIZE_INC | XCB_SIZE_HINT_P_ASPECT); + + /* NumPropSizeElements = 18 (ICCCM version 1) */ + if(length >= 18) + flags |= (XCB_SIZE_HINT_BASE_SIZE | XCB_SIZE_HINT_P_WIN_GRAVITY); + else + { + hints->base_width = 0; + hints->base_height = 0; + hints->win_gravity = 0; + } + /* get rid of unwanted bits */ + hints->flags &= flags; + + return 1; +} + +uint8_t +xcb_get_wm_size_hints_reply(xcb_connection_t *c, xcb_get_property_cookie_t cookie, + xcb_size_hints_t *hints, xcb_generic_error_t **e) +{ + xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); + uint8_t ret = xcb_get_wm_size_hints_from_reply(hints, reply); + free(reply); + return ret; +} + +/* WM_NORMAL_HINTS */ + +void +xcb_set_wm_normal_hints_checked(xcb_connection_t *c, xcb_window_t window, + xcb_size_hints_t *hints) +{ + xcb_set_wm_size_hints_checked(c, window, WM_NORMAL_HINTS, hints); +} + +void +xcb_set_wm_normal_hints(xcb_connection_t *c, xcb_window_t window, + xcb_size_hints_t *hints) +{ + xcb_set_wm_size_hints(c, window, WM_NORMAL_HINTS, hints); +} + +xcb_get_property_cookie_t +xcb_get_wm_normal_hints(xcb_connection_t *c, xcb_window_t window) +{ + return xcb_get_wm_size_hints(c, window, WM_NORMAL_HINTS); +} + +xcb_get_property_cookie_t +xcb_get_wm_normal_hints_unchecked(xcb_connection_t *c, xcb_window_t window) +{ + return xcb_get_wm_size_hints_unchecked(c, window, WM_NORMAL_HINTS); +} + +uint8_t +xcb_get_wm_normal_hints_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_size_hints_t *hints, + xcb_generic_error_t **e) +{ + return xcb_get_wm_size_hints_reply(c, cookie, hints, e); +} + +/* WM_HINTS */ + +uint32_t +xcb_wm_hints_get_urgency(xcb_wm_hints_t *hints) +{ + return (hints->flags & XCB_WM_HINT_X_URGENCY); +} + +void +xcb_wm_hints_set_input(xcb_wm_hints_t *hints, uint8_t input) +{ + hints->input = input; + hints->flags |= XCB_WM_HINT_INPUT; +} + +void +xcb_wm_hints_set_iconic(xcb_wm_hints_t *hints) +{ + hints->initial_state = XCB_WM_STATE_ICONIC; + hints->flags |= XCB_WM_HINT_STATE; +} + +void +xcb_wm_hints_set_normal(xcb_wm_hints_t *hints) +{ + hints->initial_state = XCB_WM_STATE_NORMAL; + hints->flags |= XCB_WM_HINT_STATE; +} + +void +xcb_wm_hints_set_withdrawn(xcb_wm_hints_t *hints) +{ + hints->initial_state = XCB_WM_STATE_WITHDRAWN; + hints->flags |= XCB_WM_HINT_STATE; +} + +void +xcb_wm_hints_set_none(xcb_wm_hints_t *hints) +{ + hints->flags &= ~XCB_WM_HINT_STATE; +} + +void +xcb_wm_hints_set_icon_pixmap(xcb_wm_hints_t *hints, xcb_pixmap_t icon_pixmap) +{ + hints->icon_pixmap = icon_pixmap; + hints->flags |= XCB_WM_HINT_ICON_PIXMAP; +} + +void +xcb_wm_hints_set_icon_mask(xcb_wm_hints_t *hints, xcb_pixmap_t icon_mask) +{ + hints->icon_mask = icon_mask; + hints->flags |= XCB_WM_HINT_ICON_MASK; +} + +void +xcb_wm_hints_set_icon_window(xcb_wm_hints_t *hints, xcb_window_t icon_window) +{ + hints->icon_window = icon_window; + hints->flags |= XCB_WM_HINT_ICON_WINDOW; +} + +void +xcb_wm_hints_set_window_group(xcb_wm_hints_t *hints, xcb_window_t window_group) +{ + hints->window_group = window_group; + hints->flags |= XCB_WM_HINT_WINDOW_GROUP; +} + +void +xcb_wm_hints_set_urgency(xcb_wm_hints_t *hints) +{ + hints->flags |= XCB_WM_HINT_X_URGENCY; +} + +void +xcb_set_wm_hints_checked(xcb_connection_t *c, xcb_window_t window, + xcb_wm_hints_t *hints) +{ + xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, WM_HINTS, + WM_HINTS, 32, sizeof(*hints) >> 2, hints); +} + +void +xcb_set_wm_hints(xcb_connection_t *c, xcb_window_t window, + xcb_wm_hints_t *hints) +{ + xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, WM_HINTS, WM_HINTS, 32, + sizeof(*hints) >> 2, hints); +} + +xcb_get_property_cookie_t +xcb_get_wm_hints(xcb_connection_t *c, + xcb_window_t window) +{ + return xcb_get_property(c, 0, window, WM_HINTS, WM_HINTS, 0L, + XCB_NUM_WM_HINTS_ELEMENTS); +} + +xcb_get_property_cookie_t +xcb_get_wm_hints_unchecked(xcb_connection_t *c, + xcb_window_t window) +{ + return xcb_get_property_unchecked(c, 0, window, WM_HINTS, WM_HINTS, 0L, + XCB_NUM_WM_HINTS_ELEMENTS); +} + +uint8_t +xcb_get_wm_hints_from_reply(xcb_wm_hints_t *hints, + xcb_get_property_reply_t *reply) +{ + if(!reply) + return 0; + + int length = xcb_get_property_value_length(reply); + int num_elem = length / (reply->format / 8); + + if (reply->type != WM_HINTS + || reply->format != 32 + || num_elem < XCB_NUM_WM_HINTS_ELEMENTS - 1) + return 0; + + memcpy(hints, (xcb_size_hints_t *) xcb_get_property_value(reply), length); + + if(num_elem < XCB_NUM_WM_HINTS_ELEMENTS) + hints->window_group = XCB_NONE; + + return 1; +} + +uint8_t +xcb_get_wm_hints_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_wm_hints_t *hints, + xcb_generic_error_t **e) +{ + xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); + int ret = xcb_get_wm_hints_from_reply(hints, reply); + free(reply); + return ret; +} + +/* WM_PROTOCOLS */ + +void +xcb_set_wm_protocols_checked(xcb_connection_t *c, xcb_atom_t wm_protocols, + xcb_window_t window, uint32_t list_len, + xcb_atom_t *list) +{ + xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, wm_protocols, + ATOM, 32, list_len, list); +} + +void +xcb_set_wm_protocols(xcb_connection_t *c, xcb_atom_t wm_protocols, + xcb_window_t window, uint32_t list_len, xcb_atom_t *list) +{ + xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, wm_protocols, ATOM, 32, + list_len, list); +} + +xcb_get_property_cookie_t +xcb_get_wm_protocols(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t wm_protocol_atom) +{ + return xcb_get_property(c, 0, window, wm_protocol_atom, ATOM, 0, UINT_MAX); +} + +xcb_get_property_cookie_t +xcb_get_wm_protocols_unchecked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t wm_protocol_atom) +{ + return xcb_get_property_unchecked(c, 0, window, wm_protocol_atom, ATOM, 0, + UINT_MAX); +} + +uint8_t +xcb_get_wm_protocols_from_reply(xcb_get_property_reply_t *reply, xcb_get_wm_protocols_reply_t *protocols) +{ + if(!reply || reply->type != ATOM || reply->format != 32) + return 0; + + protocols->_reply = reply; + protocols->atoms_len = xcb_get_property_value_length(protocols->_reply) / (reply->format / 8); + protocols->atoms = (xcb_atom_t *) xcb_get_property_value(protocols->_reply); + + return 1; +} + +uint8_t +xcb_get_wm_protocols_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_get_wm_protocols_reply_t *protocols, + xcb_generic_error_t **e) +{ + xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); + uint8_t ret = xcb_get_wm_protocols_from_reply(reply, protocols); + if(!ret) + free(reply); + return ret; +} + +void +xcb_get_wm_protocols_reply_wipe(xcb_get_wm_protocols_reply_t *protocols) +{ + free(protocols->_reply); +} diff --git a/icccm/xcb-icccm.pc.in b/icccm/xcb-icccm.pc.in new file mode 100644 index 0000000..0586560 --- /dev/null +++ b/icccm/xcb-icccm.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: XCB ICCCM library +Description: XCB ICCCM binding +Version: @PACKAGE_VERSION@ +Requires: xcb xcb-atom xcb-property +Libs: -L${libdir} -lxcb-icccm @LIBS@ +Cflags: -I${includedir} diff --git a/icccm/xcb_icccm.h b/icccm/xcb_icccm.h new file mode 100644 index 0000000..938fecb --- /dev/null +++ b/icccm/xcb_icccm.h @@ -0,0 +1,916 @@ +#ifndef __XCB_ICCCM_H__ +#define __XCB_ICCCM_H__ + +/* + * Copyright (C) 2008 Arnaud Fontaine + * Copyright (C) 2007-2008 Vincent Torri + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +/** + * @defgroup xcb__icccm_t XCB ICCCM Functions + * + * These functions allow easy handling of the protocol described in the + * Inter-Client Communication Conventions Manual. + * + * @{ + */ + +#include +#include "xcb_property.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief TextProperty reply structure. + */ +typedef struct { + /** Store reply to avoid memory allocation, should normally not be + used directly */ + xcb_get_property_reply_t *_reply; + /** Encoding used */ + xcb_atom_t encoding; + /** Length of the name field above */ + uint32_t name_len; + /** Property value */ + char *name; + /** Format, may be 8, 16 or 32 */ + uint8_t format; +} xcb_get_text_property_reply_t; + +/** + * @brief Deliver a GetProperty request to the X server. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param property Property atom to get. + * @return The request cookie. + * + * Allow to get a window property, in most case you might want to use + * above functions to get an ICCCM property for a given window. + */ +xcb_get_property_cookie_t xcb_get_text_property(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t property); + +/** + * @see xcb_get_text_property() + */ +xcb_get_property_cookie_t xcb_get_text_property_unchecked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t property); + +/** + * @brief Fill given structure with the property value of a window. + * @param c The connection to the X server. + * @param cookie TextProperty request cookie. + * @param prop TextProperty reply which is to be filled. + * @param e Error if any. + * @return Return 1 on success, 0 otherwise. + * + * If the function return 0 (failure), the content of prop is unmodified and + * therefore the structure must not be wiped. + * + * The parameter e supplied to this function must be NULL if + * xcb_get_text_property_unchecked() is used. Otherwise, it stores + * the error if any. prop structure members should be freed by + * xcb_get_text_property_reply_wipe(). + */ +uint8_t xcb_get_text_property_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_get_text_property_reply_t *prop, + xcb_generic_error_t **e); + +/** + * @brief Wipe prop structure members previously allocated by + * xcb_get_text_property_reply(). + * @param prop prop structure whose members is going to be freed. + */ +void xcb_get_text_property_reply_wipe(xcb_get_text_property_reply_t *prop); + +/* WM_NAME */ + +/** + * @brief Deliver a SetProperty request to set WM_NAME property value. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param encoding Encoding used for the data passed in the name parameter, the set property will also have this encoding as its type. + * @param name_len Length of name value to set. + * @param name Name value to set. + */ +void xcb_set_wm_name_checked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t encoding, + uint32_t name_len, + const char *name); + +/** + * @see xcb_set_wm_name_checked() + */ +void xcb_set_wm_name(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t encoding, uint32_t name_len, + const char *name); + +/** + * @brief Deliver a GetProperty request to the X server for WM_NAME. + * @param c The connection to the X server. + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_get_wm_name(xcb_connection_t *c, + xcb_window_t window); + +/** + * @see xcb_get_wm_name() + */ +xcb_get_property_cookie_t xcb_get_wm_name_unchecked(xcb_connection_t *c, + xcb_window_t window); + +/** + * @brief Fill given structure with the WM_NAME property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param prop WM_NAME property value. + * @param e Error if any. + * @see xcb_get_text_property_reply() + * @return Return 1 on success, 0 otherwise. + */ +uint8_t xcb_get_wm_name_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_get_text_property_reply_t *prop, + xcb_generic_error_t **e); + +/** + * @brief Set a callback on WM_NAME property changes. + * @param prophs Property handlers. + * @param long_len Length of data. + * @param handler The callback. + * @param data data given to the callback. + */ +void xcb_watch_wm_name(xcb_property_handlers_t *prophs, uint32_t long_len, + xcb_generic_property_handler_t handler, void *data); + +/* WM_ICON_NAME */ + +/** + * @brief Deliver a SetProperty request to set WM_ICON_NAME property value. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param encoding Encoding used for the data passed in the name parameter, the set property will also have this encoding as its type. + * @param name_len Length of name value to set. + * @param name Name value to set. + */ +void xcb_set_wm_icon_name_checked(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t encoding, uint32_t name_len, + const char *name); + +/** + * @see xcb_set_wm_icon_name_checked() + */ +void xcb_set_wm_icon_name(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t encoding, uint32_t name_len, + const char *name); + +/** + * @brief Send request to get WM_ICON_NAME property of a window. + * @param c The connection to the X server. + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_get_wm_icon_name(xcb_connection_t *c, + xcb_window_t window); + +/** + * @see xcb_get_wm_icon_name() + */ +xcb_get_property_cookie_t xcb_get_wm_icon_name_unchecked(xcb_connection_t *c, + xcb_window_t window); + +/** + * @brief Fill given structure with the WM_ICON_NAME property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param prop WM_ICON_NAME property value. + * @param e Error if any. + * @see xcb_get_text_property_reply() + * @return Return 1 on success, 0 otherwise. + */ +uint8_t xcb_get_wm_icon_name_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_get_text_property_reply_t *prop, + xcb_generic_error_t **e); + +/** + * @brief Set a callback on WM_ICON_NAME property changes. + * @param prophs Property handlers. + * @param long_len Length of data. + * @param handler The callback. + * @param data data given to the callback. + */ +void xcb_watch_wm_icon_name(xcb_property_handlers_t *prophs, uint32_t long_len, + xcb_generic_property_handler_t handler, + void *data); + +/* WM_CLIENT_MACHINE */ + +/** + * @brief Deliver a SetProperty request to set WM_CLIENT_MACHINE property value. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param encoding Encoding used for the data passed in the name parameter, the set property will also have this encoding as its type. + * @param name_len Length of name value to set. + * @param name Name value to set. + */ +void xcb_set_wm_client_machine_checked(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t encoding, uint32_t name_len, + const char *name); + +/** + * @see xcb_set_wm_client_machine_checked() + */ +void xcb_set_wm_client_machine(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t encoding, uint32_t name_len, + const char *name); + +/** + * @brief Send request to get WM_CLIENT_MACHINE property of a window. + * @param c The connection to the X server. + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_get_wm_client_machine(xcb_connection_t *c, + xcb_window_t window); + +/** + * @see xcb_get_wm_client_machine() + */ +xcb_get_property_cookie_t xcb_get_wm_client_machine_unchecked(xcb_connection_t *c, + xcb_window_t window); + +/** + * @brief Fill given structure with the WM_CLIENT_MACHINE property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param prop WM_CLIENT_MACHINE property value. + * @param e Error if any. + * @see xcb_get_text_property_reply() + * @return Return 1 on success, 0 otherwise. + */ +uint8_t xcb_get_wm_client_machine_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_get_text_property_reply_t *prop, + xcb_generic_error_t **e); + +/** + * @brief Set a callback on WM_CLIENT_MACHINE property changes. + * @param prophs Property handlers. + * @param long_len Length of data. + * @param handler The callback. + * @param data data given to the callback. + */ +void xcb_watch_wm_client_machine(xcb_property_handlers_t *prophs, + uint32_t long_len, + xcb_generic_property_handler_t handler, + void *data); + +/* WM_CLASS */ + +/** + * @brief WM_CLASS hint structure + */ +typedef struct { + /** Instance name */ + char *instance_name; + /** Class of application */ + char *class_name; + /** Store reply to avoid memory allocation, should normally not be + used directly */ + xcb_get_property_reply_t *_reply; +} xcb_get_wm_class_reply_t; + +/** + * @brief Deliver a GetProperty request to the X server for WM_CLASS. + * @param c The connection to the X server. + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_get_wm_class(xcb_connection_t *c, + xcb_window_t window); + +/** + * @see xcb_get_wm_class() + */ +xcb_get_property_cookie_t xcb_get_wm_class_unchecked(xcb_connection_t *c, + xcb_window_t window); + + +/** + * @brief Fill give structure with the WM_CLASS property of a window. + * @param prop The property structur to fill. + * @param reply The property request reply. + * @return Return 1 on success, 0 otherwise. + */ +uint8_t +xcb_get_wm_class_from_reply(xcb_get_wm_class_reply_t *prop, + xcb_get_property_reply_t *reply); + +/** + * @brief Fill given structure with the WM_CLASS property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param prop WM_CLASS property value. + * @param e Error if any. + * @return Return 1 on success, 0 otherwise. + * + * The parameter e supplied to this function must be NULL if + * xcb_get_wm_class_unchecked() is used. Otherwise, it stores the + * error if any. prop structure members should be freed by + * xcb_get_wm_class_reply_wipe(). + */ +uint8_t xcb_get_wm_class_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_get_wm_class_reply_t *prop, + xcb_generic_error_t **e); + +/** + * @brief Wipe prop structure members previously allocated by + * xcb_get_wm_class_reply(). + * @param prop prop structure whose members is going to be freed. + */ +void xcb_get_wm_class_reply_wipe(xcb_get_wm_class_reply_t *prop); + +/* WM_TRANSIENT_FOR */ + +/** + * @brief Send request to get WM_TRANSIENT_FOR property of a window. + * @param c The connection to the X server + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_get_wm_transient_for(xcb_connection_t *c, + xcb_window_t window); + +/** + * @see xcb_get_wm_transient_for_unchecked() + */ +xcb_get_property_cookie_t xcb_get_wm_transient_for_unchecked(xcb_connection_t *c, + xcb_window_t window); + +/** + * @brief Fill given window pointer with the WM_TRANSIENT_FOR property of a window. + * @param prop WM_TRANSIENT_FOR property value. + * @param reply The get property request reply. + * @return Return 1 on success, 0 otherwise. + */ +uint8_t +xcb_get_wm_transient_for_from_reply(xcb_window_t *prop, + xcb_get_property_reply_t *reply); +/** + * @brief Fill given structure with the WM_TRANSIENT_FOR property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param prop WM_TRANSIENT_FOR property value. + * @param e Error if any. + * @return Return 1 on success, 0 otherwise. + * + * The parameter e supplied to this function must be NULL if + * xcb_get_wm_transient_for_unchecked() is used. Otherwise, it stores + * the error if any. + */ +uint8_t xcb_get_wm_transient_for_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_window_t *prop, + xcb_generic_error_t **e); + +/* WM_SIZE_HINTS */ + +typedef enum { + XCB_SIZE_HINT_US_POSITION = 1 << 0, + XCB_SIZE_HINT_US_SIZE = 1 << 1, + XCB_SIZE_HINT_P_POSITION = 1 << 2, + XCB_SIZE_HINT_P_SIZE = 1 << 3, + XCB_SIZE_HINT_P_MIN_SIZE = 1 << 4, + XCB_SIZE_HINT_P_MAX_SIZE = 1 << 5, + XCB_SIZE_HINT_P_RESIZE_INC = 1 << 6, + XCB_SIZE_HINT_P_ASPECT = 1 << 7, + XCB_SIZE_HINT_BASE_SIZE = 1 << 8, + XCB_SIZE_HINT_P_WIN_GRAVITY = 1 << 9 +} xcb_size_hints_flags_t; + +/** + * @brief Size hints structure. + */ +typedef struct { + /** User specified flags */ + uint32_t flags; + /** User-specified position */ + int32_t x, y; + /** User-specified size */ + int32_t width, height; + /** Program-specified minimum size */ + int32_t min_width, min_height; + /** Program-specified maximum size */ + int32_t max_width, max_height; + /** Program-specified resize increments */ + int32_t width_inc, height_inc; + /** Program-specified minimum aspect ratios */ + int32_t min_aspect_num, min_aspect_den; + /** Program-specified maximum aspect ratios */ + int32_t max_aspect_num, max_aspect_den; + /** Program-specified base size */ + int32_t base_width, base_height; + /** Program-specified window gravity */ + uint32_t win_gravity; +} xcb_size_hints_t; + +/** + * @brief Set size hints to a given position. + * @param hints SIZE_HINTS structure. + * @param user_specified Is the size user-specified? + * @param x The X position. + * @param y The Y position. + */ +void xcb_size_hints_set_position(xcb_size_hints_t *hints, int user_specified, + int32_t x, int32_t y); + +/** + * @brief Set size hints to a given size. + * @param hints SIZE_HINTS structure. + * @param user_specified is the size user-specified? + * @param width The width. + * @param height The height. + */ +void xcb_size_hints_set_size(xcb_size_hints_t *hints, int user_specified, + int32_t width, int32_t height); + +/** + * @brief Set size hints to a given minimum size. + * @param hints SIZE_HINTS structure. + * @param width The minimum width. + * @param height The minimum height. + */ +void xcb_size_hints_set_min_size(xcb_size_hints_t *hints, int32_t min_width, + int32_t min_height); + +/** + * @brief Set size hints to a given maximum size. + * @param hints SIZE_HINTS structure. + * @param width The maximum width. + * @param height The maximum height. + */ +void xcb_size_hints_set_max_size(xcb_size_hints_t *hints, int32_t max_width, + int32_t max_height); + +/** + * @brief Set size hints to a given resize increments. + * @param hints SIZE_HINTS structure. + * @param width The resize increments width. + * @param height The resize increments height. + */ +void xcb_size_hints_set_resize_inc(xcb_size_hints_t *hints, int32_t width_inc, + int32_t height_inc); + +/** + * @brief Set size hints to a given aspect ratios. + * @param hints SIZE_HINTS structure. + * @param min_aspect_num The minimum aspect ratios for the width. + * @param min_aspect_den The minimum aspect ratios for the height. + * @param max_aspect_num The maximum aspect ratios for the width. + * @param max_aspect_den The maximum aspect ratios for the height. + */ +void xcb_size_hints_set_aspect(xcb_size_hints_t *hints, int32_t min_aspect_num, + int32_t min_aspect_den, int32_t max_aspect_num, + int32_t max_aspect_den); + +/** + * @brief Set size hints to a given base size. + * @param hints SIZE_HINTS structure. + * @param base_width Base width. + * @param base_height Base height. + */ +void xcb_size_hints_set_base_size(xcb_size_hints_t *hints, int32_t base_width, + int32_t base_height); + +/** + * @brief Set size hints to a given window gravity. + * @param hints SIZE_HINTS structure. + * @param win_gravity Window gravity value. + */ +void xcb_size_hints_set_win_gravity(xcb_size_hints_t *hints, + uint32_t win_gravity); + +/** + * @brief Deliver a ChangeProperty request to set a value to a given property. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param property Property to set value for. + * @param hints Hints value to set. + */ +void xcb_set_wm_size_hints_checked(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t property, xcb_size_hints_t *hints); + +/** + * @see xcb_set_wm_size_hints_checked() + */ +void xcb_set_wm_size_hints(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t property, xcb_size_hints_t *hints); + +/** + * @brief Send request to get size hints structure for the named property. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param property Specify the property name. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_get_wm_size_hints(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t property); + +/** + * @see xcb_get_wm_size_hints() + */ +xcb_get_property_cookie_t xcb_get_wm_size_hints_unchecked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t property); + +/** + * @brief Fill given structure with the size hints of the named property. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param hints Size hints structure. + * @param e Error if any. + * @return Return 1 on success, 0 otherwise. + * + * The parameter e supplied to this function must be NULL if + * xcb_get_wm_size_hints_unchecked() is used. Otherwise, it stores + * the error if any. The returned pointer should be freed. + */ +uint8_t xcb_get_wm_size_hints_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_size_hints_t *hints, + xcb_generic_error_t **e); + +/* WM_NORMAL_HINTS */ + +/** + * @brief Deliver a ChangeProperty request to set WM_NORMAL_HINTS property value. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param hints Hints value to set. + */ +void xcb_set_wm_normal_hints_checked(xcb_connection_t *c, xcb_window_t window, + xcb_size_hints_t *hints); + +/** + * @see xcb_set_wm_normal_hints_checked() + */ +void xcb_set_wm_normal_hints(xcb_connection_t *c, xcb_window_t window, + xcb_size_hints_t *hints); + +/** + * @brief Send request to get WM_NORMAL_HINTS property of a window. + * @param c The connection to the X server. + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_get_wm_normal_hints(xcb_connection_t *c, + xcb_window_t window); + +/** + * @see xcb_get_wm_normal_hints() + */ +xcb_get_property_cookie_t xcb_get_wm_normal_hints_unchecked(xcb_connection_t *c, + xcb_window_t window); + +/** + * @brief Fill given structure with the WM_NORMAL_HINTS property of a window. + * @param hints WM_NORMAL_HINTS property value. + * @param reply The get property request reply. + * @return Return 1 on success, 0 otherwise. + */ +uint8_t +xcb_get_wm_size_hints_from_reply(xcb_size_hints_t *hints, + xcb_get_property_reply_t *reply); + +/** + * @brief Fill given structure with the WM_NORMAL_HINTS property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param hints WM_NORMAL_HINTS property value. + * @param e Error if any. + * @return Return 1 on success, 0 otherwise. + * + * The parameter e supplied to this function must be NULL if + * xcb_get_wm_normal_hints_unchecked() is used. Otherwise, it stores + * the error if any. The returned pointer should be freed. + */ +uint8_t xcb_get_wm_normal_hints_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_size_hints_t *hints, + xcb_generic_error_t **e); + +/* WM_HINTS */ + +/** + * @brief WM hints structure (may be extended in the future). + */ +typedef struct { + /** Marks which fields in this structure are defined */ + int32_t flags; + /** Does this application rely on the window manager to get keyboard + input? */ + uint32_t input; + /** See below */ + int32_t initial_state; + /** Pixmap to be used as icon */ + xcb_pixmap_t icon_pixmap; + /** Window to be used as icon */ + xcb_window_t icon_window; + /** Initial position of icon */ + int32_t icon_x, icon_y; + /** Icon mask bitmap */ + xcb_pixmap_t icon_mask; + /* Identifier of related window group */ + xcb_window_t window_group; +} xcb_wm_hints_t; + +/** Number of elements in this structure */ +#define XCB_NUM_WM_HINTS_ELEMENTS 9 + +/** + * @brief WM_HINTS window states. + */ +typedef enum { + XCB_WM_STATE_WITHDRAWN = 0, + XCB_WM_STATE_NORMAL = 1, + XCB_WM_STATE_ICONIC = 3 +} xcb_wm_state_t; + +typedef enum { + XCB_WM_HINT_INPUT = (1L << 0), + XCB_WM_HINT_STATE = (1L << 1), + XCB_WM_HINT_ICON_PIXMAP = (1L << 2), + XCB_WM_HINT_ICON_WINDOW = (1L << 3), + XCB_WM_HINT_ICON_POSITION = (1L << 4), + XCB_WM_HINT_ICON_MASK = (1L << 5), + XCB_WM_HINT_WINDOW_GROUP = (1L << 6), + XCB_WM_HINT_X_URGENCY = (1L << 8) +} xcb_wm_t; + +#define XCB_WM_ALL_HINTS (XCB_WM_HINT_INPUT | XCB_WM_HINT_STATE |\ + XCB_WM_HINT_ICON_PIXMAP | XCB_WM_HINT_ICON_WINDOW |\ + XCB_WM_HINT_ICON_POSITION | XCB_WM_HINT_ICON_MASK |\ + XCB_WM_HINT_WINDOW_GROUP) + +/** + * @brief Get urgency hint. + * @param hints WM_HINTS structure. + * @return Urgency hint value. + */ +uint32_t xcb_wm_hints_get_urgency(xcb_wm_hints_t *hints); + +/** + * @brief Set input focus. + * @param hints WM_HINTS structure. + * @param input Input focus. + */ +void xcb_wm_hints_set_input(xcb_wm_hints_t *hints, uint8_t input); + +/** + * @brief Set hints state to 'iconic'. + * @param hints WM_HINTS structure. + */ +void xcb_wm_hints_set_iconic(xcb_wm_hints_t *hints); + +/** + * @brief Set hints state to 'normal'. + * @param hints WM_HINTS structure. + */ +void xcb_wm_hints_set_normal(xcb_wm_hints_t *hints); + +/** + * @brief Set hints state to 'withdrawn'. + * @param hints WM_HINTS structure. + */ +void xcb_wm_hints_set_withdrawn(xcb_wm_hints_t *hints); + +/** + * @brief Set hints state to none. + * @param hints WM_HINTS structure. + */ +void xcb_wm_hints_set_none(xcb_wm_hints_t *hints); + +/** + * @brief Set pixmap to be used as icon. + * @param hints WM_HINTS structure. + * @param icon_pixmap Pixmap. + */ +void xcb_wm_hints_set_icon_pixmap(xcb_wm_hints_t *hints, + xcb_pixmap_t icon_pixmap); + +/** + * @brief Set icon mask bitmap. + * @param hints WM_HINTS structure. + * @param icon_mask Pixmap. + */ +void xcb_wm_hints_set_icon_mask(xcb_wm_hints_t *hints, xcb_pixmap_t icon_mask); + +/** + * @brief Set window identifier to be used as icon. + * @param hints WM_HINTS structure. + * @param icon_window Window X identifier. + */ +void xcb_wm_hints_set_icon_window(xcb_wm_hints_t *hints, + xcb_window_t icon_window); + +/** + * @brief Set identifier of related window group. + * @param hints WM_HINTS structure. + * @param window_group Window X identifier. + */ +void xcb_wm_hints_set_window_group(xcb_wm_hints_t *hints, + xcb_window_t window_group); + +/** + * @brief Set urgency hints flag. + * @param hints WM_HINTS structure. + */ +void xcb_wm_hints_set_urgency(xcb_wm_hints_t *hints); + +/** + * @brief Deliver a SetProperty request to set WM_HINTS property value. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param hints Hints value to set. + */ +void xcb_set_wm_hints_checked(xcb_connection_t *c, xcb_window_t window, + xcb_wm_hints_t *hints); + +/** + * @see xcb_set_wm_hints_checked() + */ +void xcb_set_wm_hints(xcb_connection_t *c, xcb_window_t window, + xcb_wm_hints_t *hints); + +/** + * @brief Send request to get WM_HINTS property of a window. + * @param c The connection to the X server. + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_get_wm_hints(xcb_connection_t *c, + xcb_window_t window); + +/** + * @see xcb_get_wm_hints() + */ +xcb_get_property_cookie_t xcb_get_wm_hints_unchecked(xcb_connection_t *c, + xcb_window_t window); + +/** + * @brief Fill given structure with the WM_HINTS property of a window. + * @param hints WM_HINTS property value. + * @param reply The get property request reply. + * @return Return 1 on success, 0 otherwise. + */ +uint8_t +xcb_get_wm_hints_from_reply(xcb_wm_hints_t *hints, + xcb_get_property_reply_t *reply); + +/** + * @brief Fill given structure with the WM_HINTS property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param hints WM_HINTS property value. + * @param e Error if any. + * @return Return 1 on success, 0 otherwise. + * + * The parameter e supplied to this function must be NULL if + * xcb_get_wm_hints_unchecked() is used. Otherwise, it stores the + * error if any. The returned pointer should be freed. + */ +uint8_t xcb_get_wm_hints_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_wm_hints_t *hints, + xcb_generic_error_t **e); + +/* WM_PROTOCOLS */ + +/** + * @brief Deliver a SetProperty request to set WM_PROTOCOLS property value. + * @param c The connection to the X server. + * @param wm_protocols The WM_PROTOCOLS atom. + * @param window Window X identifier. + * @param list_len Atom list len. + * @param list Atom list. + */ +void xcb_set_wm_protocols_checked(xcb_connection_t *c, xcb_atom_t wm_protocols, + xcb_window_t window, uint32_t list_len, + xcb_atom_t *list); + +/** + * @see xcb_set_wm_protocols_checked() + */ +void xcb_set_wm_protocols(xcb_connection_t *c, xcb_atom_t wm_protocols, + xcb_window_t window, uint32_t list_len, + xcb_atom_t *list); + +/** + * @brief WM_PROTOCOLS structure. + */ +typedef struct { + /** Length of the atoms list */ + uint32_t atoms_len; + /** Atoms list */ + xcb_atom_t *atoms; + /** Store reply to avoid memory allocation, should normally not be + used directly */ + xcb_get_property_reply_t *_reply; +} xcb_get_wm_protocols_reply_t; + +/** + * @brief Send request to get WM_PROTOCOLS property of a given window. + * @param c The connection to the X server. + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_get_wm_protocols(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t wm_protocol_atom); + +/** + * @see xcb_get_wm_protocols() + */ +xcb_get_property_cookie_t xcb_get_wm_protocols_unchecked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t wm_protocol_atom); + +/** + * @brief Fill the given structure with the WM_PROTOCOLS property of a window. + * @param reply The reply of the GetProperty request. + * @param protocols WM_PROTOCOLS property value. + * @return Return 1 on success, 0 otherwise. + * + * protocols structure members should be freed by + * xcb_get_wm_protocols_reply_wipe(). + */ +uint8_t xcb_get_wm_protocols_from_reply(xcb_get_property_reply_t *reply, + xcb_get_wm_protocols_reply_t *protocols); +/** + * @brief Fill the given structure with the WM_PROTOCOLS property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param protocols WM_PROTOCOLS property value. + * @param e Error if any. + * @return Return 1 on success, 0 otherwise. + * + * The parameter e supplied to this function must be NULL if + * xcb_get_wm_protocols_unchecked() is used. Otherwise, it stores the + * error if any. protocols structure members should be freed by + * xcb_get_wm_protocols_reply_wipe(). + */ +uint8_t xcb_get_wm_protocols_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_get_wm_protocols_reply_t *protocols, + xcb_generic_error_t **e); + +/** + * @brief Wipe protocols structure members previously allocated by + * xcb_get_wm_protocols_reply(). + * @param protocols protocols structure whose members is going to be freed. + */ +void xcb_get_wm_protocols_reply_wipe(xcb_get_wm_protocols_reply_t *protocols); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __XCB_ICCCM_H__ */ diff --git a/image/Makefile.am b/image/Makefile.am new file mode 100644 index 0000000..a18b228 --- /dev/null +++ b/image/Makefile.am @@ -0,0 +1,44 @@ +MAINTAINERCLEANFILES = Makefile.in + +lib_LTLIBRARIES = libxcb-image.la + +xcbinclude_HEADERS = xcb_image.h xcb_pixel.h + +AM_CFLAGS = $(CWARNFLAGS) + +XCB_IMAGE_LIBS = libxcb-image.la + +libxcb_image_la_SOURCES = xcb_image.c +libxcb_image_la_CPPFLAGS = $(XCB_CFLAGS) $(XCB_SHM_CFLAGS) $(XCB_AUX_CFLAGS) +libxcb_image_la_LIBADD = $(XCB_LIBS) $(XCB_SHM_LIBS) $(XCB_AUX_LIBS) + +pkgconfig_DATA = xcb-image.pc + +EXTRA_DIST=xcb-image.pc.in + +EXTRA_PROGRAMS = test_xcb_image test_xcb_image_shm test_formats test_bitmap + +check_PROGRAMS = test_swap + +TESTS=test_swap + +test_swap_SOURCES = test_swap.c +test_swap_CPPFLAGS = $(XCB_CFLAGS) $(XCB_SHM_CFLAGS) $(XCB_AUX_CFLAGS) +test_swap_LDADD = $(XCB_LIBS) $(XCB_AUX_LIBS) $(XCB_IMAGE_LIBS) + +test_xcb_image_SOURCES = test_xcb_image.c +test_xcb_image_CPPFLAGS = $(XCB_CFLAGS) $(XCB_SHM_CFLAGS) $(XCB_AUX_CFLAGS) +test_xcb_image_LDADD = $(XCB_LIBS) $(XCB_AUX_LIBS) $(XCB_IMAGE_LIBS) + +test_xcb_image_shm_SOURCES = test_xcb_image_shm.c +test_xcb_image_shm_CPPFLAGS = $(XCB_CFLAGS) $(XCB_SHM_CFLAGS) $(XCB_AUX_CFLAGS) +test_xcb_image_shm_LDADD = $(XCB_LIBS) $(XCB_SHM_LIBS) \ + $(XCB_AUX_LIBS) $(XCB_IMAGE_LIBS) + +test_formats_SOURCES = test_formats.c +test_formats_CPPFLAGS = $(XCB_CFLAGS) $(XCB_SHM_CFLAGS) $(XCB_AUX_CFLAGS) +test_formats_LDADD = $(XCB_LIBS) $(XCB_AUX_LIBS) $(XCB_IMAGE_LIBS) + +test_bitmap_SOURCES = test_bitmap.c +test_bitmap_CPPFLAGS = $(XCB_CFLAGS) $(XCB_SHM_CFLAGS) $(XCB_AUX_CFLAGS) +test_bitmap_LDADD = $(XCB_LIBS) $(XCB_AUX_LIBS) $(XCB_IMAGE_LIBS) diff --git a/image/test.xbm b/image/test.xbm new file mode 100644 index 0000000..804b996 --- /dev/null +++ b/image/test.xbm @@ -0,0 +1,471 @@ +#define test_width 216 +#define test_height 208 +static uint8_t test_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x5f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0x6f, 0xf6, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0xff, 0x3a, 0x13, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0d, 0x02, 0x51, 0x71, 0x0e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2f, 0x20, 0xd9, 0x88, + 0x9b, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, + 0xac, 0x44, 0x4e, 0x1c, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1e, 0x40, 0x02, 0x44, 0x60, 0xe2, 0xfc, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x25, 0x09, 0x90, 0x22, 0x13, 0xb7, 0x9a, 0x1e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x40, 0x10, 0x89, + 0x18, 0xe3, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x04, 0x08, + 0x01, 0x10, 0xc8, 0xa8, 0xd5, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x83, 0x80, 0x20, 0x40, 0x82, 0x00, 0x66, 0x9c, 0xec, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x08, 0x08, 0x24, 0x12, 0x93, 0x5b, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x12, 0x80, 0x04, 0x01, 0x00, 0x80, + 0x19, 0x33, 0xfa, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x80, 0x80, 0x00, + 0x20, 0x08, 0x12, 0xc4, 0x68, 0x26, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x02, 0x04, 0x24, 0x00, 0x01, 0x40, 0x24, 0x8c, 0xcd, 0x3f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x80, 0x49, 0x10, 0x90, 0x00, 0x21, 0x20, 0x08, 0x11, 0x43, 0xd9, + 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, + 0xff, 0xff, 0x0b, 0x00, 0x60, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x30, 0xb9, 0xf2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x97, 0x04, 0x08, 0xfe, 0x05, 0x30, 0x10, 0x12, 0x20, 0x20, + 0x04, 0x00, 0x80, 0x48, 0x0c, 0xa3, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3e, 0x92, 0x20, 0x49, 0x40, 0x3e, 0x0e, 0x82, + 0x00, 0x84, 0x25, 0x01, 0x80, 0x00, 0x80, 0xc8, 0x34, 0xed, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x25, 0x01, 0x04, 0x01, 0x08, + 0xd0, 0x17, 0x00, 0x80, 0x25, 0x01, 0xad, 0x04, 0x12, 0x20, 0x23, 0x4c, + 0x6a, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x02, 0x48, + 0x92, 0x20, 0x41, 0x92, 0x9e, 0x80, 0x24, 0x24, 0x29, 0x00, 0x04, 0x00, + 0x10, 0x98, 0xcc, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x4f, 0x10, 0x01, 0x90, 0x24, 0x40, 0x12, 0xf0, 0x00, 0x24, 0x41, 0x0b, + 0xa9, 0x10, 0x00, 0x00, 0x04, 0xd9, 0x96, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x00, 0x92, 0x48, 0x02, 0x04, 0x09, 0xc0, 0x84, 0x8f, + 0x29, 0x2d, 0xf8, 0xa9, 0x02, 0x00, 0x00, 0x20, 0x90, 0xf4, 0x1e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x24, 0x91, 0x04, 0x50, 0x22, 0x24, + 0x1b, 0x12, 0x7a, 0x48, 0xca, 0x03, 0x21, 0x10, 0x00, 0x00, 0x48, 0x93, + 0xff, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x24, 0x92, 0x20, + 0x81, 0xda, 0x24, 0xc8, 0x16, 0xd0, 0xe7, 0x50, 0xd2, 0xbf, 0x03, 0x00, + 0x80, 0x00, 0x30, 0x29, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, + 0x20, 0x80, 0x24, 0x41, 0x12, 0x2a, 0x41, 0xb2, 0x80, 0x33, 0x0e, 0x7e, + 0x88, 0x1c, 0x01, 0x00, 0xa0, 0x24, 0x69, 0x75, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x82, 0x44, 0x11, 0x24, 0x09, 0x90, 0xa4, 0x4d, 0xd2, 0x92, + 0x9e, 0xd3, 0x83, 0x6b, 0x62, 0x00, 0x00, 0x10, 0x22, 0xff, 0x7f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x42, 0x04, 0x92, 0x24, 0x6b, 0x53, 0x32, + 0x59, 0x90, 0x16, 0xfa, 0xb4, 0xf4, 0xff, 0x0f, 0x01, 0x00, 0x90, 0x68, + 0x4a, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x90, 0x24, 0x11, 0x24, + 0x49, 0xda, 0x82, 0xc5, 0x92, 0xd2, 0xd0, 0x9e, 0x1e, 0x00, 0x78, 0x0a, + 0x00, 0x00, 0x05, 0xd2, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x02, + 0x44, 0xb2, 0x65, 0xea, 0x49, 0x9e, 0x2c, 0x4b, 0x1a, 0xd2, 0xeb, 0xe3, + 0xff, 0xc7, 0x09, 0x00, 0x20, 0x68, 0xff, 0xd6, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x0b, 0x90, 0x40, 0x92, 0x24, 0x09, 0x5f, 0xd2, 0x64, 0x59, 0x72, + 0x56, 0x7f, 0xfd, 0xdf, 0x1f, 0x12, 0x00, 0x20, 0x49, 0x92, 0xde, 0x01, + 0x00, 0x00, 0x00, 0x80, 0x41, 0x92, 0x4c, 0x92, 0x24, 0x25, 0xc9, 0x8b, + 0x2e, 0xcb, 0x92, 0x4b, 0x5a, 0x2f, 0x75, 0xf4, 0x04, 0x00, 0x00, 0x41, + 0xf6, 0x74, 0x01, 0x00, 0x00, 0x00, 0x40, 0x49, 0x02, 0x00, 0xba, 0xb6, + 0xfd, 0x49, 0xf8, 0x74, 0x6d, 0x4b, 0x72, 0xed, 0xdb, 0xff, 0xcf, 0x53, + 0x00, 0x00, 0x48, 0xb6, 0xd7, 0x03, 0x00, 0x00, 0x00, 0x60, 0x48, 0x10, + 0xc9, 0x93, 0x24, 0x00, 0x7b, 0xc3, 0xa6, 0x69, 0x58, 0x5a, 0xfb, 0xfa, + 0xa5, 0xbe, 0x16, 0x00, 0x00, 0x92, 0xa4, 0xfd, 0x03, 0x00, 0x00, 0x00, + 0x30, 0x01, 0x20, 0x5d, 0xa2, 0xfe, 0x7f, 0x01, 0x4f, 0x1a, 0xcd, 0x6b, + 0x6a, 0xa9, 0x5f, 0xff, 0xf3, 0x24, 0x01, 0x40, 0xc0, 0xb4, 0xf4, 0x03, + 0x00, 0x00, 0x00, 0x2c, 0x88, 0x84, 0x89, 0xb6, 0x00, 0x24, 0x7d, 0x69, + 0xf2, 0x34, 0xad, 0x99, 0x2d, 0xf7, 0xff, 0x9f, 0x4b, 0x00, 0x00, 0x92, + 0xa6, 0xad, 0x07, 0x00, 0x00, 0x00, 0x06, 0x91, 0x24, 0xe9, 0xa4, 0xfd, + 0xa5, 0xa9, 0x4b, 0x93, 0xe7, 0x34, 0x63, 0xf9, 0xfc, 0xd5, 0xef, 0x16, + 0x00, 0x40, 0x90, 0xb4, 0xbd, 0x07, 0x00, 0x00, 0x00, 0x6a, 0x80, 0x4c, + 0x96, 0xbe, 0x2d, 0xfd, 0x2f, 0x7c, 0x5e, 0x9c, 0x67, 0xad, 0xa5, 0xfd, + 0xff, 0xbf, 0x29, 0x00, 0x00, 0x92, 0x76, 0xed, 0x06, 0x00, 0x00, 0x00, + 0x05, 0x12, 0x48, 0x53, 0x25, 0x65, 0x25, 0xf4, 0xe5, 0xd3, 0x72, 0x9c, + 0x35, 0xdf, 0xf6, 0x7f, 0xf5, 0x56, 0x00, 0x00, 0x92, 0xa4, 0xed, 0x0f, + 0x00, 0x00, 0x80, 0x49, 0x20, 0x59, 0x38, 0xec, 0xff, 0xff, 0xad, 0x2f, + 0x5d, 0xd3, 0x33, 0xe6, 0x24, 0xed, 0xff, 0xdf, 0x2d, 0x01, 0x40, 0x80, + 0x24, 0xbd, 0x07, 0x00, 0x00, 0xc0, 0x48, 0x24, 0x49, 0x87, 0x37, 0x21, + 0xa0, 0xbd, 0xf4, 0x79, 0x4f, 0xc7, 0x9c, 0xde, 0xf6, 0xff, 0xff, 0x5b, + 0x08, 0x00, 0x92, 0xfc, 0xe9, 0x0e, 0x00, 0x00, 0x20, 0x89, 0x40, 0xd3, + 0xf4, 0x49, 0xff, 0xff, 0xe7, 0x2f, 0xcf, 0x79, 0x9c, 0x53, 0xb2, 0x35, + 0xff, 0xff, 0x37, 0x00, 0x40, 0x90, 0x24, 0xef, 0x0e, 0x00, 0x00, 0x30, + 0x91, 0x49, 0x32, 0x2d, 0xff, 0x6b, 0xb7, 0xbd, 0xbc, 0x3c, 0xef, 0x79, + 0xce, 0xde, 0xd6, 0xfd, 0xff, 0x9f, 0x00, 0x00, 0x92, 0xa6, 0xad, 0x0b, + 0x00, 0x00, 0x30, 0x11, 0x89, 0x8c, 0xcb, 0x5b, 0xba, 0xaf, 0xf6, 0xd7, + 0xe7, 0x35, 0xe7, 0x59, 0xb3, 0xfb, 0xff, 0xff, 0x7f, 0x04, 0x40, 0x80, + 0xe4, 0xb9, 0x1f, 0x00, 0x00, 0x48, 0x22, 0x91, 0x66, 0x79, 0xeb, 0xff, + 0xff, 0xdf, 0xbe, 0xbe, 0xe7, 0x8c, 0x75, 0x6b, 0x4a, 0xfa, 0xbf, 0x7f, + 0x00, 0x00, 0x82, 0x24, 0xef, 0x0e, 0x00, 0x00, 0x4c, 0x22, 0xb2, 0x79, + 0x5e, 0xfa, 0x5b, 0xa9, 0xfd, 0xeb, 0xf5, 0x9c, 0x3d, 0xc6, 0xcc, 0xee, + 0xed, 0x01, 0xf8, 0x00, 0x40, 0x82, 0xb6, 0xa9, 0x1b, 0x00, 0x00, 0x94, + 0x64, 0x66, 0x8e, 0xd3, 0x97, 0xfe, 0xff, 0xd7, 0xdf, 0x9f, 0x7b, 0xf3, + 0x3c, 0x35, 0x59, 0x6b, 0x00, 0x70, 0x00, 0x00, 0x40, 0xe4, 0xed, 0x1e, + 0x00, 0x00, 0x92, 0xc4, 0x34, 0xf3, 0xfc, 0xfd, 0x5f, 0xad, 0x7d, 0xfa, + 0x7a, 0xce, 0x8e, 0xb3, 0x76, 0x2f, 0xfd, 0x00, 0xe0, 0x04, 0x00, 0x9a, + 0x26, 0xaf, 0x1e, 0x00, 0x00, 0x13, 0x88, 0xcc, 0xb5, 0x3f, 0xbf, 0xff, + 0xff, 0xd7, 0xef, 0xef, 0xbd, 0x79, 0x6a, 0xde, 0xec, 0xab, 0x01, 0xc0, + 0x00, 0x00, 0x40, 0xb6, 0xbd, 0x1b, 0x00, 0x00, 0x05, 0x91, 0xeb, 0x5c, + 0xeb, 0xeb, 0xff, 0xff, 0xff, 0x7e, 0xef, 0x6b, 0xef, 0xcd, 0x99, 0xb3, + 0xe4, 0x07, 0x80, 0x00, 0x40, 0x49, 0xb2, 0xe5, 0x1a, 0x00, 0x80, 0x20, + 0x32, 0xb1, 0xe7, 0x79, 0x7f, 0xf7, 0xff, 0xfd, 0xeb, 0xbd, 0xfe, 0x2c, + 0x3d, 0x6b, 0xb6, 0xaf, 0x06, 0x80, 0x00, 0x00, 0x41, 0x96, 0xfe, 0x1e, + 0x00, 0x80, 0x44, 0xb2, 0x9b, 0xf9, 0xde, 0xff, 0xff, 0xff, 0x7f, 0xbf, + 0xf7, 0xbb, 0xb3, 0x77, 0xce, 0xce, 0xb6, 0x0d, 0x80, 0x01, 0x00, 0x49, + 0xf2, 0x94, 0x1f, 0x00, 0x40, 0x49, 0x44, 0xe6, 0x9e, 0x77, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xbf, 0xf7, 0x7e, 0xd6, 0xbc, 0xd9, 0xba, 0x3b, 0x80, + 0x00, 0x00, 0x64, 0x93, 0xf7, 0x1b, 0x00, 0x40, 0x89, 0xec, 0x7e, 0x67, + 0xbd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xce, 0xdb, 0x99, 0x33, 0x37, + 0xd3, 0x36, 0x80, 0x01, 0x80, 0x24, 0xda, 0xd6, 0x1e, 0x00, 0x20, 0x90, + 0x99, 0x99, 0x7b, 0xef, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xef, 0xbd, 0x37, + 0x63, 0xf3, 0x66, 0xdb, 0x7a, 0x80, 0x00, 0x00, 0x24, 0x59, 0xde, 0x1f, + 0x00, 0x60, 0x12, 0xb3, 0xf7, 0xdd, 0xfb, 0xfe, 0xff, 0xff, 0xff, 0xff, + 0xbf, 0xf7, 0xfe, 0x6e, 0xce, 0xdd, 0x6d, 0xd7, 0x80, 0x00, 0x80, 0x20, + 0xcb, 0xfb, 0x1f, 0x00, 0x10, 0x20, 0x6e, 0x66, 0x76, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xef, 0xde, 0xdb, 0x9b, 0x99, 0xb3, 0x5d, 0x6b, 0x81, + 0x00, 0x40, 0x96, 0x59, 0x6a, 0x1f, 0x00, 0x98, 0xc4, 0xe4, 0xdf, 0xff, + 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7b, 0x6f, 0x7b, 0x37, 0x7f, + 0xb3, 0xdd, 0x83, 0x00, 0x00, 0xb0, 0xed, 0xef, 0x1d, 0x00, 0x10, 0x88, + 0x9e, 0xdd, 0xcd, 0xbd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xed, + 0x6c, 0xe6, 0xcc, 0x76, 0x6d, 0xc1, 0x00, 0x40, 0x91, 0x24, 0x7b, 0x1f, + 0x00, 0x08, 0xd1, 0xf1, 0x66, 0x76, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xdf, 0xbd, 0xbf, 0xd9, 0xdd, 0xdd, 0xb6, 0x47, 0x00, 0x00, 0xd8, + 0xb4, 0xad, 0x1f, 0x00, 0x24, 0x24, 0x6f, 0xf6, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xb7, 0x9d, 0x33, 0xd9, 0x96, 0x4e, + 0x00, 0x20, 0x49, 0xf7, 0xfd, 0x1e, 0x00, 0x48, 0xe4, 0xac, 0xb9, 0xdd, + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xdd, 0x76, 0xb6, + 0xb7, 0xfd, 0x7a, 0x00, 0x00, 0x44, 0x96, 0xb7, 0x1f, 0x00, 0x02, 0x9a, + 0xbe, 0x6f, 0x77, 0xff, 0xff, 0x7f, 0x61, 0xd9, 0xff, 0xff, 0xff, 0xfd, + 0xdd, 0x66, 0xed, 0x66, 0x5b, 0x37, 0x00, 0x90, 0x64, 0xb9, 0xf6, 0x1f, + 0x00, 0x02, 0xc9, 0xf3, 0xee, 0xfd, 0xff, 0xff, 0x2f, 0x24, 0x4f, 0xfe, + 0xff, 0xff, 0x7f, 0x37, 0xdb, 0xcd, 0x7c, 0xff, 0x3a, 0x00, 0x88, 0x24, + 0xdb, 0xde, 0x1a, 0x00, 0x13, 0x31, 0x6f, 0xbb, 0xdf, 0xff, 0xff, 0x21, + 0xa0, 0x64, 0xf3, 0xff, 0xff, 0xe7, 0xff, 0x96, 0xbb, 0x9b, 0xa5, 0x1d, + 0x00, 0x60, 0x32, 0xe9, 0xdb, 0x0f, 0x00, 0x65, 0xe6, 0x3c, 0xfb, 0xf6, + 0xff, 0x7f, 0x10, 0xa4, 0xb5, 0x9d, 0xfe, 0xdf, 0xdf, 0xdd, 0x6d, 0x32, + 0xb3, 0x7d, 0x0d, 0x00, 0x0b, 0x93, 0x7c, 0x7b, 0x0f, 0x00, 0x89, 0xdc, + 0xb3, 0xed, 0xfb, 0xff, 0x1f, 0x10, 0x90, 0x92, 0xd9, 0xfe, 0x7f, 0xff, + 0x77, 0xdb, 0xee, 0x6e, 0xdb, 0x0e, 0x00, 0x20, 0xdd, 0x66, 0x6f, 0x0f, + 0x80, 0x91, 0x5a, 0xfb, 0xbe, 0xef, 0xff, 0x0f, 0x10, 0xda, 0x92, 0xee, + 0xff, 0xff, 0xff, 0xf7, 0xb7, 0xcd, 0xee, 0xde, 0x07, 0x00, 0x24, 0x49, + 0xb6, 0xed, 0x0f, 0x00, 0x12, 0x6b, 0xcd, 0xf3, 0xbe, 0xff, 0x07, 0x08, + 0x48, 0xda, 0x76, 0xb7, 0xff, 0xff, 0xdd, 0x6e, 0xba, 0x99, 0x65, 0x03, + 0x40, 0x92, 0xe4, 0xba, 0xbd, 0x0e, 0x80, 0x62, 0xed, 0x7d, 0x5f, 0xf7, + 0xff, 0x01, 0x08, 0x28, 0xc9, 0x26, 0xbb, 0xff, 0xff, 0xff, 0x99, 0xb7, + 0xbb, 0x7d, 0x03, 0x00, 0x89, 0x64, 0xdb, 0xf6, 0x07, 0x40, 0x0c, 0x35, + 0xe7, 0x79, 0xdd, 0xff, 0x01, 0x84, 0xa5, 0x7d, 0xba, 0xdd, 0xfe, 0x7f, + 0xbf, 0xbf, 0x6d, 0x76, 0xdb, 0x01, 0x00, 0x48, 0x36, 0xdb, 0xd6, 0x07, + 0xc0, 0x88, 0xb4, 0xb6, 0xbf, 0xff, 0x7f, 0x00, 0x0c, 0x24, 0x44, 0xdb, + 0xed, 0xff, 0xdf, 0xef, 0x6e, 0xdb, 0x6e, 0xb7, 0x00, 0x80, 0x44, 0x93, + 0xed, 0x5b, 0x07, 0x40, 0x91, 0xd2, 0xfa, 0xfc, 0xf6, 0x7f, 0x00, 0x02, + 0xb4, 0x35, 0xd9, 0xef, 0xff, 0xff, 0xfb, 0xef, 0xb6, 0xc9, 0xe4, 0x00, + 0x10, 0x24, 0xd9, 0x6d, 0xfb, 0x03, 0x00, 0x27, 0xfe, 0xd3, 0xd6, 0xdb, + 0x3f, 0x00, 0xa2, 0x94, 0xb4, 0xdb, 0x7c, 0xff, 0xff, 0xbf, 0xd9, 0xad, + 0xdb, 0x7d, 0x00, 0x40, 0x32, 0xd9, 0xb6, 0xef, 0x03, 0x60, 0xe4, 0x5a, + 0x5f, 0x5f, 0xff, 0x1f, 0x00, 0x02, 0x52, 0x92, 0xec, 0xb6, 0xff, 0xff, + 0xef, 0xff, 0x6d, 0xb6, 0x3b, 0x00, 0x28, 0x90, 0xcc, 0xbe, 0xfd, 0x03, + 0xa0, 0x88, 0xeb, 0xf9, 0xfd, 0xf5, 0x1f, 0x00, 0x82, 0x53, 0xbb, 0x6d, + 0xf7, 0xff, 0xf9, 0xff, 0x6f, 0xdb, 0x6d, 0x1b, 0x00, 0x04, 0xc9, 0x66, + 0xdb, 0x57, 0x03, 0xa0, 0x52, 0xaf, 0xa7, 0x97, 0xff, 0x0f, 0x00, 0x51, + 0x48, 0xda, 0x66, 0xdb, 0xff, 0xf8, 0xdf, 0xed, 0xbe, 0xed, 0x0e, 0x00, + 0x92, 0x64, 0x32, 0xeb, 0xf6, 0x01, 0x20, 0x63, 0xbd, 0xbc, 0xfc, 0xfa, + 0x0f, 0x00, 0x09, 0x20, 0x89, 0x3e, 0xff, 0xff, 0xe0, 0x7f, 0xdf, 0x6f, + 0xdb, 0x07, 0x00, 0x01, 0x24, 0xbb, 0xed, 0xfe, 0x01, 0xa0, 0xce, 0xf5, + 0xf6, 0xdb, 0xdf, 0x07, 0x00, 0x41, 0xad, 0x5f, 0xf2, 0xed, 0xff, 0xc0, + 0xff, 0xbf, 0xdd, 0x92, 0x03, 0x00, 0x44, 0xb2, 0xd9, 0x7d, 0xfb, 0x01, + 0xe0, 0xaa, 0xdf, 0x9b, 0x7f, 0xfb, 0x07, 0x80, 0x28, 0x21, 0x64, 0xbb, + 0x7f, 0x7f, 0x80, 0xff, 0xf6, 0xbb, 0xee, 0x03, 0x80, 0x22, 0x99, 0xed, + 0xb6, 0xff, 0x00, 0x90, 0xb8, 0x5e, 0x5b, 0x6b, 0xed, 0x03, 0x00, 0x01, + 0xa6, 0x6d, 0xdb, 0xf6, 0x7f, 0x00, 0xff, 0xff, 0xf6, 0xcd, 0x00, 0x40, + 0x10, 0xc9, 0x6c, 0xff, 0xf7, 0x00, 0xa0, 0xe3, 0x72, 0xeb, 0xef, 0xff, + 0x03, 0x80, 0xe0, 0x90, 0x24, 0xdb, 0xbd, 0x3f, 0x00, 0xfe, 0xdb, 0x6f, + 0xfb, 0x00, 0x00, 0x89, 0x4c, 0xb6, 0xd9, 0x7e, 0x00, 0x70, 0xaf, 0xaf, + 0x6f, 0xb5, 0xde, 0x03, 0x80, 0x94, 0x92, 0xb6, 0xf9, 0xf6, 0x3f, 0x00, + 0xfc, 0xbf, 0xdd, 0x7b, 0x00, 0x10, 0x48, 0x26, 0xb3, 0xdf, 0x7f, 0x00, + 0x70, 0xd8, 0xae, 0xfd, 0xff, 0xf7, 0x03, 0x80, 0x00, 0xd2, 0x36, 0xcf, + 0xdf, 0x3f, 0x00, 0xb8, 0x6d, 0xdf, 0x16, 0x00, 0x48, 0x44, 0xb2, 0xfb, + 0x6c, 0x3f, 0x00, 0x50, 0x75, 0xfd, 0xa5, 0xd5, 0xfe, 0x01, 0x40, 0xd1, + 0x12, 0xa2, 0x7d, 0xfb, 0x1f, 0x00, 0xf0, 0xff, 0xbf, 0x0d, 0x00, 0x20, + 0x12, 0x9b, 0xcd, 0xf6, 0x3f, 0x00, 0x90, 0xd5, 0xa7, 0xfd, 0x77, 0xab, + 0x03, 0x40, 0x1c, 0xc8, 0xbe, 0x6d, 0xfb, 0x1f, 0x00, 0xe0, 0xff, 0xee, + 0x07, 0x00, 0x04, 0x91, 0xc9, 0x7e, 0xbf, 0x1f, 0x00, 0x30, 0x57, 0xbf, + 0xa6, 0xde, 0xfd, 0x01, 0x40, 0x40, 0x6b, 0xd3, 0x6e, 0xef, 0x0f, 0x00, + 0xc0, 0xeb, 0x7d, 0x03, 0x00, 0x90, 0xc8, 0x6c, 0x76, 0xfb, 0x0f, 0x00, + 0x70, 0x5c, 0xe5, 0xf7, 0xfa, 0xeb, 0x01, 0x40, 0x50, 0x49, 0x92, 0xf4, + 0xfd, 0x0f, 0x00, 0xc0, 0xff, 0xdb, 0x01, 0x80, 0x44, 0x44, 0x66, 0xbb, + 0x6f, 0x0f, 0x00, 0xd0, 0xf1, 0x95, 0xf6, 0x6f, 0xad, 0x01, 0x40, 0x08, + 0x78, 0xdb, 0xb6, 0xef, 0x0f, 0x00, 0x00, 0xdf, 0xd6, 0x00, 0x00, 0x20, + 0x32, 0xb3, 0xdb, 0xfd, 0x0f, 0x00, 0x10, 0xd7, 0xf7, 0xb6, 0xd8, 0xeb, + 0x03, 0x20, 0x43, 0x27, 0xd9, 0xb6, 0xfd, 0x0f, 0x00, 0x00, 0xff, 0x7e, + 0x00, 0x40, 0x12, 0x93, 0xd9, 0xec, 0xb6, 0x07, 0x00, 0x70, 0x55, 0xdd, + 0xf6, 0x6f, 0xbb, 0x01, 0x40, 0x28, 0xa1, 0x6f, 0xb6, 0xb7, 0x0f, 0x00, + 0x00, 0xde, 0x1f, 0x00, 0x80, 0x88, 0xd8, 0xcc, 0x66, 0xff, 0x03, 0x00, + 0x70, 0xf4, 0xf5, 0xdb, 0xaa, 0xee, 0x01, 0x60, 0x28, 0x2d, 0x49, 0xf7, + 0xf6, 0x07, 0x00, 0x00, 0x7c, 0x0f, 0x00, 0x08, 0x48, 0x66, 0x6e, 0xfb, + 0xef, 0x03, 0x00, 0xd0, 0xd5, 0xdf, 0x52, 0xff, 0xda, 0x03, 0x20, 0xa3, + 0xa5, 0xd9, 0xb2, 0xff, 0x07, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x20, 0x22, + 0x33, 0x37, 0xbf, 0xfd, 0x01, 0x00, 0x70, 0x5f, 0xf7, 0xfe, 0xab, 0x6b, + 0x02, 0xa0, 0xa8, 0xb4, 0x6d, 0xdf, 0xf6, 0x07, 0x00, 0x00, 0xf8, 0x01, + 0x00, 0x12, 0x33, 0x11, 0xd9, 0xdd, 0xff, 0x01, 0x00, 0x70, 0x75, 0xd5, + 0x52, 0xea, 0x8a, 0x03, 0x20, 0x84, 0x36, 0x69, 0xba, 0xdb, 0x07, 0x00, + 0x00, 0xf0, 0x01, 0x00, 0x81, 0xc8, 0xcc, 0xdd, 0xed, 0xff, 0x00, 0x00, + 0x60, 0xd5, 0xdf, 0xf6, 0xae, 0x6b, 0x03, 0x00, 0xa1, 0xa4, 0x6d, 0xdf, + 0xfe, 0x07, 0x00, 0x00, 0x60, 0x00, 0x40, 0x44, 0xc6, 0xcc, 0x64, 0xb7, + 0xfd, 0x00, 0x00, 0xe0, 0x55, 0xf7, 0xd6, 0xea, 0xba, 0x07, 0x20, 0x94, + 0x94, 0x6d, 0xfb, 0xdb, 0x07, 0x00, 0x00, 0x20, 0x00, 0x20, 0x20, 0x32, + 0x76, 0x77, 0xff, 0x7f, 0x00, 0x00, 0x60, 0x7d, 0xd5, 0xb6, 0x3f, 0xaf, + 0x06, 0xa0, 0xa4, 0x95, 0x6c, 0x9b, 0xee, 0x07, 0x00, 0x00, 0x18, 0x00, + 0x10, 0x92, 0x15, 0x73, 0xbb, 0xd9, 0x3f, 0x00, 0x00, 0xe0, 0xf5, 0xff, + 0xf7, 0x6a, 0xa9, 0x06, 0x80, 0xa2, 0xb4, 0x6d, 0xfb, 0xfb, 0x07, 0x00, + 0x00, 0x04, 0x00, 0x84, 0x88, 0xc8, 0x99, 0xdd, 0xff, 0x3f, 0x00, 0x00, + 0xe0, 0x8b, 0xff, 0x96, 0x6a, 0xb6, 0x0a, 0xa0, 0x94, 0x96, 0x64, 0xdb, + 0xee, 0x07, 0x00, 0x00, 0x03, 0x08, 0x20, 0x60, 0x66, 0xec, 0xee, 0xb6, + 0x1d, 0x00, 0x00, 0xc0, 0x7e, 0xa5, 0xf4, 0xab, 0x55, 0x0d, 0x20, 0xe7, + 0xd4, 0x6d, 0xdb, 0xfb, 0x07, 0x00, 0x80, 0x00, 0x00, 0x09, 0x12, 0x33, + 0x67, 0x77, 0xff, 0x0f, 0x00, 0x00, 0xc0, 0xfa, 0xff, 0xb7, 0x7a, 0x55, + 0x19, 0x90, 0x91, 0xd4, 0x64, 0xdb, 0xee, 0x07, 0x00, 0x40, 0x00, 0x81, + 0x04, 0x88, 0x91, 0x3b, 0xbb, 0xfd, 0x0f, 0x00, 0x00, 0xc0, 0xab, 0xbf, + 0xed, 0x4e, 0xbb, 0x32, 0x20, 0x94, 0x96, 0x6c, 0xff, 0xfa, 0x03, 0x00, + 0x30, 0x40, 0x20, 0x20, 0x64, 0xcc, 0xdc, 0xdd, 0xff, 0x07, 0x00, 0x00, + 0xc0, 0xeb, 0xea, 0xfd, 0xd5, 0xaa, 0x2a, 0x20, 0xd7, 0xb0, 0x6d, 0x93, + 0xef, 0x07, 0x00, 0x08, 0x00, 0x08, 0x01, 0x23, 0xee, 0xee, 0xee, 0xfb, + 0x03, 0x00, 0x00, 0xc0, 0xfe, 0xff, 0x2d, 0xdd, 0x6a, 0x49, 0xd0, 0x90, + 0x9a, 0x64, 0xdf, 0xea, 0x07, 0x00, 0x03, 0x80, 0x40, 0x8c, 0x98, 0x33, + 0xb3, 0xbb, 0xff, 0x01, 0x00, 0x00, 0xc0, 0xa5, 0x7b, 0x6d, 0xa7, 0x56, + 0xc5, 0xa0, 0x94, 0x94, 0x6f, 0xd3, 0xbb, 0x07, 0x80, 0x10, 0x0c, 0x12, + 0x40, 0xc6, 0xb9, 0xdb, 0xfb, 0xfd, 0x01, 0x00, 0x00, 0x80, 0x97, 0xee, + 0xdf, 0xba, 0x54, 0x1a, 0xa1, 0xe5, 0xd2, 0x64, 0x7e, 0xee, 0x07, 0x60, + 0x02, 0x80, 0x00, 0x31, 0x62, 0xcc, 0xdc, 0xee, 0x7f, 0x00, 0x00, 0x00, + 0x80, 0xff, 0xff, 0xdb, 0xaa, 0xb5, 0x8a, 0x86, 0x98, 0x96, 0x6d, 0x9b, + 0xea, 0x07, 0x98, 0x00, 0x22, 0x44, 0x88, 0x39, 0x77, 0x77, 0xff, 0x7f, + 0x00, 0x00, 0x00, 0x80, 0x7d, 0x77, 0xba, 0x7b, 0x2d, 0x55, 0x3c, 0xa6, + 0xb4, 0x6c, 0xf6, 0xaf, 0x07, 0x07, 0x90, 0x88, 0x20, 0x42, 0x9c, 0xbb, + 0xbb, 0xbb, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xbd, 0xbf, 0x55, 0x53, + 0xa5, 0xb2, 0xa1, 0xb4, 0xc9, 0x9f, 0xda, 0xcf, 0x28, 0x24, 0x42, 0x08, + 0x31, 0xe6, 0xcc, 0xdd, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xef, + 0xb7, 0xbd, 0xde, 0x12, 0xd1, 0xac, 0x95, 0x4d, 0xf2, 0x56, 0x9f, 0x88, + 0x80, 0x10, 0xc2, 0x9c, 0x73, 0x77, 0xef, 0xfe, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0xbf, 0xfb, 0xed, 0xeb, 0x35, 0x95, 0x72, 0xa2, 0x35, 0xcd, 0xb6, + 0xd6, 0x2f, 0x21, 0x24, 0x04, 0x31, 0xc6, 0x98, 0x33, 0xf7, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0xd6, 0x6a, 0x7f, 0x5b, 0xab, 0x2d, 0x28, 0x23, + 0x65, 0xd9, 0xb6, 0x55, 0x5f, 0x88, 0x08, 0x43, 0x0c, 0x61, 0xde, 0xdd, + 0xfb, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x76, 0xff, 0x4d, 0xd7, 0x4d, + 0x4a, 0xa5, 0x29, 0x2d, 0xdb, 0xbe, 0x55, 0x1f, 0x22, 0x42, 0x28, 0xc2, + 0x39, 0xe7, 0xee, 0xee, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x7f, + 0xfb, 0xb6, 0xb6, 0x95, 0x70, 0x2e, 0xa5, 0xd9, 0x24, 0x5d, 0x5f, 0x8a, + 0x28, 0x88, 0x31, 0x9e, 0x39, 0x73, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, + 0x00, 0xec, 0xb7, 0xdf, 0x6c, 0xb5, 0x65, 0x26, 0xa3, 0x39, 0x9b, 0xfc, + 0x85, 0x5d, 0x21, 0x04, 0x63, 0x1c, 0xe6, 0xdd, 0xbd, 0xfb, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0xb8, 0xfa, 0xb6, 0x6f, 0x4d, 0x9a, 0x28, 0x59, + 0x4d, 0xd3, 0x2f, 0xf5, 0x3f, 0x8c, 0xd1, 0x18, 0xc6, 0x31, 0xf6, 0xdd, + 0xfe, 0xff, 0xfe, 0x01, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xef, 0xb9, 0xb6, + 0x25, 0xe1, 0x4d, 0x69, 0xba, 0x6c, 0xad, 0x3c, 0x41, 0x14, 0x84, 0xe9, + 0x9e, 0x37, 0xf7, 0xff, 0xff, 0xfb, 0x03, 0x00, 0x00, 0x00, 0x70, 0x5d, + 0x3d, 0x9f, 0x3d, 0x6d, 0x26, 0x52, 0x59, 0xb6, 0x6d, 0xab, 0x7f, 0x14, + 0x82, 0xe1, 0x39, 0xe6, 0xdd, 0xfb, 0xff, 0xbf, 0xff, 0x01, 0x00, 0x00, + 0x00, 0xf0, 0xf6, 0x6f, 0x77, 0xcd, 0x92, 0xd0, 0x52, 0x4b, 0xb3, 0x49, + 0x0b, 0x3a, 0x41, 0x61, 0x38, 0x9e, 0x73, 0xee, 0xdc, 0xff, 0xff, 0xfd, + 0x03, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xd7, 0x65, 0xda, 0x66, 0x63, 0x9d, + 0xf2, 0x36, 0x7b, 0x6a, 0x7f, 0x14, 0x18, 0x8e, 0xe7, 0xd9, 0x7b, 0xff, + 0xff, 0xef, 0xff, 0x03, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xdd, 0xb6, + 0xc9, 0x4c, 0x46, 0x9a, 0x64, 0xcb, 0x5b, 0xed, 0x06, 0xc6, 0xe3, 0x71, + 0xde, 0xbd, 0xff, 0xff, 0x7f, 0xff, 0x07, 0x00, 0x00, 0x00, 0xc0, 0x7f, + 0x7f, 0xff, 0x59, 0x37, 0x75, 0xbb, 0x96, 0x66, 0xdb, 0x56, 0xf7, 0xe0, + 0xf2, 0x74, 0x9e, 0x77, 0xef, 0xfd, 0xff, 0xeb, 0xed, 0x03, 0x00, 0x00, + 0x00, 0xc0, 0xea, 0xdf, 0xb3, 0xdb, 0xde, 0xc6, 0x81, 0xb0, 0x6c, 0xba, + 0xb4, 0xf6, 0x38, 0x18, 0x3c, 0xe7, 0x9c, 0xfb, 0xff, 0x7f, 0xff, 0xff, + 0x07, 0x00, 0x00, 0x00, 0x80, 0xff, 0xf7, 0x6e, 0x66, 0xd9, 0x99, 0xac, + 0xa4, 0xcd, 0x96, 0xa5, 0xea, 0x03, 0xa7, 0xcf, 0x79, 0xef, 0xfd, 0xff, + 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfd, 0xef, 0xdf, + 0x6f, 0xef, 0x72, 0x65, 0xd9, 0xb6, 0xad, 0xe8, 0xc1, 0xe1, 0xf1, 0xbe, + 0x7b, 0xef, 0xff, 0xdf, 0x7a, 0xfb, 0x07, 0x00, 0x00, 0x00, 0x00, 0xfe, + 0x5f, 0xdd, 0x9d, 0xac, 0x99, 0x84, 0x29, 0xcd, 0x3c, 0x4f, 0x9d, 0x7d, + 0x3c, 0x9e, 0xe7, 0xbe, 0xff, 0xff, 0xff, 0xff, 0xef, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xff, 0x77, 0x7b, 0x33, 0xe7, 0x5a, 0x49, 0x9b, 0x65, + 0x59, 0x75, 0x07, 0x97, 0xf7, 0xbb, 0xef, 0xff, 0xff, 0xdb, 0xfe, 0xff, + 0x07, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf7, 0x3f, 0xe7, 0xcf, 0x9c, 0x51, + 0x4d, 0xb0, 0x6d, 0x4b, 0xc9, 0xd3, 0xf5, 0x79, 0xfe, 0xfb, 0xff, 0xff, + 0xdb, 0xda, 0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xef, 0xde, + 0xdd, 0xf3, 0x4d, 0x52, 0x36, 0xcb, 0xd2, 0x3a, 0x7e, 0x3c, 0xde, 0xe7, + 0xbe, 0xff, 0x7f, 0xda, 0xff, 0xdf, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xf8, + 0xff, 0xfb, 0xdd, 0x73, 0x8f, 0xa5, 0x9a, 0xe6, 0xd9, 0xb6, 0xe2, 0x4e, + 0xc7, 0xf7, 0xfd, 0xff, 0xff, 0xff, 0xf7, 0xf6, 0xff, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0xff, 0xff, 0x7f, 0xee, 0x79, 0xb2, 0xb2, 0x2c, 0x9f, + 0xb6, 0x54, 0xfe, 0xfb, 0x79, 0xbf, 0xff, 0xff, 0x5f, 0xda, 0xff, 0xfa, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xf7, 0xbf, 0xe7, 0x4b, + 0xb4, 0x69, 0xd3, 0x2c, 0x25, 0xbd, 0xbc, 0xcf, 0xf7, 0xfd, 0xff, 0xd7, + 0xf6, 0xfe, 0xdf, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xbf, 0x9d, + 0xf1, 0x3e, 0x57, 0x25, 0xcb, 0xb6, 0x6d, 0xa9, 0xb5, 0xef, 0xfb, 0xff, + 0xff, 0xff, 0xd5, 0xda, 0xd6, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xff, 0xff, 0xfb, 0xcf, 0xf5, 0x25, 0x65, 0xd9, 0x66, 0x5b, 0x4a, 0xfa, + 0xf9, 0x7e, 0xff, 0xff, 0xff, 0xf6, 0xd6, 0xdf, 0xfa, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xff, 0xef, 0x3e, 0xf7, 0x9f, 0x5b, 0x92, 0x6c, + 0xdb, 0x52, 0xe5, 0xbe, 0xdf, 0xff, 0xff, 0xbf, 0x51, 0xda, 0xfa, 0x7f, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x7b, 0x9f, 0xe7, + 0x4c, 0xb3, 0x4d, 0xd3, 0x54, 0xd9, 0xe7, 0xfb, 0xff, 0xff, 0x5f, 0xdc, + 0xfa, 0xdf, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x7f, + 0xe7, 0xf9, 0x3a, 0xd3, 0xa6, 0xe9, 0xb6, 0xa5, 0xca, 0xf9, 0xfd, 0xff, + 0xff, 0x83, 0x42, 0xd2, 0xff, 0xfb, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0xff, 0xfd, 0xbf, 0xef, 0x4f, 0xd5, 0x64, 0xdb, 0x26, 0x4d, 0x30, + 0x7f, 0xff, 0xff, 0xff, 0x91, 0xda, 0xdb, 0xda, 0xdf, 0x1f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0xff, 0xbf, 0xff, 0x7d, 0xbe, 0xb5, 0x6d, 0x97, + 0x6d, 0x93, 0x56, 0xdf, 0xff, 0xff, 0x7f, 0x81, 0x4a, 0xda, 0x7f, 0xff, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xef, 0xeb, 0xbb, + 0xa6, 0x4d, 0x73, 0xcd, 0x92, 0xaa, 0xfe, 0xff, 0xff, 0x1f, 0x01, 0x6a, + 0x5b, 0xfb, 0xfb, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xfd, 0xbf, 0x5f, 0x3b, 0xdb, 0x36, 0xbb, 0x26, 0x4c, 0xf9, 0xff, 0xff, + 0x0f, 0xa3, 0x2a, 0xe9, 0x7f, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xee, 0xff, 0xff, 0xfe, 0xfe, 0xcc, 0x91, 0xec, 0x93, 0x6d, 0x93, + 0xf2, 0xff, 0xff, 0x03, 0x00, 0x6a, 0x6d, 0x6f, 0xff, 0x1f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xf7, 0x6f, 0x76, 0xb6, 0xcd, + 0x76, 0xc9, 0x2a, 0xe9, 0xff, 0xff, 0x00, 0x02, 0x24, 0xed, 0xf9, 0xed, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xdf, 0xff, + 0xd9, 0x66, 0x9b, 0x6c, 0x93, 0x54, 0xc5, 0xff, 0x3f, 0x00, 0x01, 0x95, + 0xb5, 0xaf, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, + 0xff, 0xff, 0xfd, 0xae, 0x7d, 0xde, 0x6d, 0xf6, 0xa1, 0x8a, 0xff, 0x0f, + 0x00, 0x81, 0x90, 0xb4, 0xfd, 0xfd, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xcd, 0xb2, 0xdb, 0x2c, 0xcb, + 0x54, 0xfe, 0x01, 0x00, 0x01, 0xd2, 0xb6, 0xb7, 0xff, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x39, 0xdb, 0x76, + 0xb3, 0x4b, 0xb6, 0x0a, 0xfe, 0x00, 0x00, 0x01, 0x48, 0xda, 0xfe, 0xff, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, + 0xcf, 0xb9, 0x6d, 0xb6, 0xd9, 0xa5, 0x75, 0x1c, 0x00, 0x80, 0x80, 0x20, + 0xdb, 0xda, 0xbe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0xff, 0xff, 0xff, 0x77, 0x96, 0xd9, 0x26, 0xb3, 0x4d, 0x82, 0x11, 0x00, + 0x80, 0x80, 0x24, 0x6d, 0xff, 0xf7, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xbb, 0x67, 0xdb, 0xdd, 0x36, 0xd9, + 0x54, 0x60, 0x00, 0xc0, 0x00, 0x92, 0x65, 0x6b, 0xff, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x4f, 0x7d, 0x96, + 0xd9, 0x6c, 0x36, 0xad, 0xc2, 0x00, 0x60, 0x00, 0xc8, 0xb6, 0x6d, 0xff, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, + 0xff, 0xc8, 0x76, 0xbb, 0xcb, 0x64, 0x52, 0x02, 0x03, 0x10, 0x00, 0x64, + 0xda, 0xff, 0xfb, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0xff, 0xff, 0x5f, 0xd7, 0x4d, 0x33, 0x99, 0xdd, 0x96, 0x04, 0x2c, + 0x1c, 0x40, 0x22, 0xdb, 0xb6, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xdf, 0xb5, 0xed, 0xe6, 0x36, 0x9b, + 0x6c, 0x29, 0xf0, 0x03, 0x00, 0x99, 0x6c, 0xfb, 0xfd, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x7f, 0x35, 0xbb, + 0xec, 0x76, 0x33, 0x91, 0x02, 0x00, 0x00, 0x00, 0x64, 0x67, 0xdf, 0xff, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, + 0xbf, 0x6f, 0x9b, 0x9d, 0xc9, 0xce, 0x36, 0x49, 0x00, 0x00, 0x00, 0x93, + 0xb1, 0xdd, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0xff, 0x6a, 0x76, 0xbb, 0xdd, 0xd9, 0x64, 0x12, 0x01, + 0x00, 0x40, 0x98, 0xdd, 0x6d, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xdf, 0x66, 0x73, 0x33, 0xbb, + 0x9d, 0x4d, 0x00, 0x00, 0x00, 0x63, 0xe6, 0xf6, 0xff, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xed, 0xfd, + 0xee, 0xee, 0x36, 0x73, 0x2b, 0x04, 0x00, 0xa0, 0x38, 0x75, 0xbf, 0xff, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f, 0xd9, 0xec, 0xce, 0x66, 0x66, 0x66, 0x22, 0x04, 0x00, 0xc6, + 0x99, 0xbb, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5e, 0xb3, 0xdb, 0xb9, 0xcd, 0xc9, 0x88, 0x89, + 0x00, 0x68, 0x31, 0xee, 0xdd, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xbe, 0xbb, 0x9b, 0x3f, + 0xbb, 0x33, 0x23, 0x04, 0x00, 0x8c, 0xf3, 0xee, 0xff, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x67, + 0x76, 0x77, 0xb2, 0x66, 0xce, 0x0c, 0xd1, 0xd6, 0xe3, 0x79, 0xf7, 0xff, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0xfd, 0xef, 0xe6, 0xee, 0xce, 0x9c, 0x31, 0x16, 0x00, 0x3c, + 0x9e, 0xfb, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x78, 0x9f, 0xdb, 0xdc, 0x9d, 0x99, 0x33, 0xc6, + 0xc1, 0xff, 0x8f, 0xe7, 0xbb, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf7, 0xbd, 0xbb, 0x33, + 0x7b, 0xee, 0x18, 0x1e, 0x50, 0xf0, 0xf9, 0xfe, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x7b, + 0xf7, 0x77, 0xf7, 0xe6, 0x9c, 0xe3, 0xf0, 0x4d, 0xff, 0x7c, 0xef, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xdf, 0x76, 0x7f, 0xcf, 0x9e, 0x73, 0x8f, 0x07, 0xff, 0x0b, + 0xdf, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xee, 0xcd, 0xdd, 0x9d, 0x7b, 0xf7, 0x7c, + 0x7a, 0x00, 0xf0, 0xe7, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0xbf, 0xdd, 0x7b, + 0x6b, 0x9e, 0xf3, 0xe1, 0xff, 0xff, 0x7d, 0xff, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, + 0xb7, 0xbb, 0x7b, 0xee, 0x79, 0x8f, 0x0f, 0xfa, 0x2f, 0xff, 0xf7, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0xff, 0x77, 0xef, 0xdd, 0x77, 0x7c, 0xfe, 0x02, 0xe8, + 0xcf, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xef, 0xee, 0xdd, 0xb3, 0xcf, 0xf3, + 0xf1, 0xff, 0xff, 0xf9, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfb, 0xff, 0xbf, + 0xef, 0xbe, 0xcf, 0x8f, 0xfe, 0x5f, 0xfe, 0xff, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0xbf, 0xbb, 0xf7, 0xde, 0x79, 0x3e, 0xff, 0x52, 0xd2, 0xdf, 0xff, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0xef, 0xef, 0xef, 0x3c, 0xef, 0xf9, 0xf8, 0xff, 0xff, + 0xf7, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xee, 0xdc, 0xf7, 0xfe, 0xe7, + 0x97, 0xfe, 0xff, 0xfe, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbf, + 0xef, 0xbf, 0x3e, 0xff, 0xda, 0xf6, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0xbf, 0xf7, 0xfe, 0xf7, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xff, 0xde, 0xbd, 0xef, 0xfb, 0xd7, 0xff, 0xbf, + 0xfd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xf7, 0x7d, 0xbf, + 0xff, 0xd2, 0xf6, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xbf, + 0xef, 0xfb, 0xfd, 0xfd, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0xff, 0xef, 0xbe, 0xf7, 0xef, 0xef, 0xff, 0xff, 0xff, 0x3f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfb, 0xdf, 0xbf, 0xff, 0xff, 0xff, + 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x7f, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, + 0xfe, 0xff, 0xfb, 0xf7, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf0, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xfd, 0xff, 0xff, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfc, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/image/test_bitmap.c b/image/test_bitmap.c new file mode 100644 index 0000000..3464743 --- /dev/null +++ b/image/test_bitmap.c @@ -0,0 +1,169 @@ +/* + * Copyright © 2008 Bart Massey + * Copyright © 2008 Julien Danjou + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +#include +#include +#include +#include +#include +#include "../aux/xcb_aux.h" +#include "../event/xcb_event.h" +#include "xcb_image.h" + +#include "test.xbm" + +static xcb_window_t make_window(xcb_connection_t *c, + xcb_screen_t *s, + uint32_t bg, + uint32_t fg, + uint32_t width, + uint32_t height) { + uint32_t mask = 0; + xcb_params_cw_t cwa; + xcb_window_t w; + xcb_void_cookie_t check_cookie; + xcb_generic_error_t *error; + xcb_visualtype_t *v = xcb_aux_find_visual_by_id(s, s->root_visual); + assert(v); + XCB_AUX_ADD_PARAM(&mask, &cwa, back_pixel, bg); + XCB_AUX_ADD_PARAM(&mask, &cwa, border_pixel, fg); + XCB_AUX_ADD_PARAM(&mask, &cwa, override_redirect, 1); + XCB_AUX_ADD_PARAM(&mask, &cwa, event_mask, + XCB_EVENT_MASK_BUTTON_PRESS | + XCB_EVENT_MASK_EXPOSURE); + w = xcb_generate_id(c); + check_cookie = xcb_aux_create_window_checked(c, + s->root_depth, w, s->root, 0, 0, width, height, 1, + XCB_WINDOW_CLASS_INPUT_OUTPUT, v->visual_id, mask, &cwa); + error = xcb_request_check(c, check_cookie); + assert(!error); + check_cookie = xcb_map_window_checked(c, w); + error = xcb_request_check(c, check_cookie); + assert(!error); + return w; +} + +void process_events(xcb_connection_t *c, + xcb_gcontext_t g, + xcb_window_t w, + xcb_pixmap_t p, + uint32_t width, + uint32_t height) { + xcb_generic_event_t *e; + xcb_void_cookie_t cookie; + + while ((e = xcb_wait_for_event(c))) { + uint32_t r = XCB_EVENT_RESPONSE_TYPE(e); + xcb_generic_error_t *err; + + fprintf(stderr, "event %d\n", r); + switch (r) { + case XCB_EXPOSE: + case XCB_MAP_NOTIFY: + cookie = xcb_copy_area_checked(c, p, w, g, + 0, 0, 0, 0, + width, height); + assert(!xcb_request_check(c, cookie)); + break; + case XCB_BUTTON_PRESS: + exit(0); + break; + case 0: + err = (xcb_generic_error_t *) e; + printf("error: %d (sequence %d)\n", + err->error_code, (unsigned int) err->full_sequence); + exit(1); + default: + break; + } + free(e); + } +} + +#define INSET_X 31 +#define INSET_Y 32 + +int main(int argc, char **argv) { + uint32_t width = test_width - 2 * INSET_X; + uint32_t height = test_height - 2 * INSET_Y; + int snum; + xcb_void_cookie_t check_cookie; + xcb_window_t w; + xcb_gcontext_t gc; + xcb_pixmap_t pix; + xcb_connection_t *c = xcb_connect(0, &snum); + xcb_screen_t *s = xcb_aux_get_screen(c, snum); + xcb_alloc_named_color_cookie_t bg_cookie = + xcb_alloc_named_color(c, s->default_colormap, + strlen("white"), "white"); + xcb_alloc_named_color_cookie_t fg_cookie = + xcb_alloc_named_color(c, s->default_colormap, + strlen("black"), "black"); + xcb_alloc_named_color_reply_t *bg_reply = + xcb_alloc_named_color_reply(c, bg_cookie, 0); + xcb_alloc_named_color_reply_t *fg_reply = + xcb_alloc_named_color_reply(c, fg_cookie, 0); + uint32_t fg, bg; + xcb_image_t *image, *native_image, *subimage; + uint32_t mask = 0; + xcb_params_gc_t gcv; + + assert(bg_reply && fg_reply); + bg = bg_reply->pixel; + fg = fg_reply->pixel; + free(bg_reply); + free(fg_reply); + w = make_window(c, s, bg, fg, width, height); + gc = xcb_generate_id(c); + check_cookie = xcb_create_gc_checked(c, gc, w, 0, 0); + assert(!xcb_request_check(c, check_cookie)); + image = xcb_image_create_from_bitmap_data((uint8_t *)test_bits, + test_width, test_height); + native_image = xcb_image_native(c, image, 1); + assert(native_image); + if (native_image != image) + xcb_image_destroy(image); + subimage = xcb_image_subimage(native_image, INSET_X, INSET_Y, + width, height, + 0, 0, 0); + assert(subimage); + xcb_image_destroy(native_image); + subimage->format = XCB_IMAGE_FORMAT_XY_BITMAP; + pix = xcb_generate_id(c); + xcb_create_pixmap(c, s->root_depth, pix, w, + subimage->width, subimage->height); + gc = xcb_generate_id(c); + XCB_AUX_ADD_PARAM(&mask, &gcv, foreground, fg); + XCB_AUX_ADD_PARAM(&mask, &gcv, background, bg); + xcb_aux_create_gc(c, gc, pix, mask, &gcv); + xcb_image_put(c, pix, gc, subimage, 0, 0, 0); + process_events(c, gc, w, pix, width, height); + xcb_disconnect(c); + return 1; +} diff --git a/image/test_formats.c b/image/test_formats.c new file mode 100644 index 0000000..be3b217 --- /dev/null +++ b/image/test_formats.c @@ -0,0 +1,202 @@ +/* + * Copyright © 2008 Bart Massey + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +#include +#include +#include +#include +#include "../aux/xcb_aux.h" +#include "../aux/xcb_bitops.h" +#include "xcb_image.h" + +#define WIDTH 50 +#define HEIGHT 50 + +static uint32_t +color (uint32_t depth, uint32_t x, uint32_t y) +{ + uint32_t p; + + if (depth == 1) { + extern long random(); + int frac = random() % (WIDTH * HEIGHT); + p = x * y >= frac; + return p; + } + depth /= 3; + p = ((1 << depth) - 1) * x * y / WIDTH / HEIGHT; + return (p << depth) | (p << (2 * depth)); +} + +static xcb_image_t *create_image(xcb_connection_t *c, int depth, int format) +{ + xcb_image_t *im; + int x, y; + printf("Image depth %d, format %d\n", depth, format); + im = xcb_image_create_native(c, WIDTH, HEIGHT, + format, depth, 0, 0, 0); + for(x = 0; x < WIDTH; ++x) + for(y = 0; y < HEIGHT; ++y) + xcb_image_put_pixel(im, x, y, color(depth, x, y)); + return im; +} + +static xcb_window_t create_window(xcb_connection_t *c, xcb_screen_t *root) +{ + static const uint32_t mask = XCB_CW_EVENT_MASK; + static const uint32_t values[] = { XCB_EVENT_MASK_EXPOSURE }; + unsigned int seq; + xcb_window_t w = xcb_generate_id(c); + seq = xcb_create_window(c, root->root_depth, w, root->root, 30, 30, WIDTH, HEIGHT, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, root->root_visual, mask, values).sequence; + printf("CreateWindow sequence %d, depth %d\n", seq, root->root_depth); + seq = xcb_map_window(c, w).sequence; + printf("MapWindow sequence %d\n", seq); + return w; +} + +static xcb_pixmap_t create_pixmap(xcb_connection_t *c, xcb_drawable_t d, uint8_t depth) +{ + xcb_pixmap_t p = xcb_generate_id(c); + unsigned int seq; + seq = xcb_create_pixmap(c, depth, p, d, WIDTH, HEIGHT).sequence; + printf("CreatePixmap sequence %d, depth %d\n", seq, depth); + return p; +} + +static xcb_gcontext_t create_gcontext(xcb_connection_t *c, + xcb_drawable_t d, + xcb_screen_t *root) +{ + static const uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND; + const uint32_t values[] = { root->black_pixel, 0xffff }; + unsigned int seq; + xcb_gcontext_t gc = xcb_generate_id(c); + seq = xcb_create_gc(c, gc, d, mask, values).sequence; + printf("CreateGC sequence %d\n", seq); + return gc; +} + + +typedef struct { + char *name; + xcb_image_format_t format; + uint8_t depth; +} format_t; + +static format_t formats[] = { + {"z-pixmap", XCB_IMAGE_FORMAT_Z_PIXMAP, 24}, + {"xy-bitmap", XCB_IMAGE_FORMAT_XY_BITMAP, 1}, + {"xy-pixmap-1", XCB_IMAGE_FORMAT_XY_PIXMAP, 1}, + {"xy-pixmap-24", XCB_IMAGE_FORMAT_XY_PIXMAP, 24}, + {0, 0, 0} +}; + +static format_t * +parse_format (char *name) { + format_t *f; + for (f = formats; f->name; f++) + if (!strcmp(name, f->name)) + return f; + fprintf(stderr, "%s: bad format: known formats are:\n", name); + for (f = formats; f->name; f++) + fprintf(stderr, "\t%s\n", f->name); + exit(1); +} + +int main(int argc, char **argv) +{ + int screen, depth; + format_t *format = &formats[0]; + xcb_screen_t *root; + xcb_visualtype_t *visual; + xcb_image_t *im; + xcb_drawable_t d, w = XCB_NONE; + xcb_gcontext_t dgc, wgc = 0; + xcb_generic_event_t *ev; + xcb_connection_t *c = xcb_connect(0, &screen); + if(!c) + { + printf("Connection failed.\n"); + exit(1); + } + root = xcb_aux_get_screen(c, screen); + assert(root); + visual = xcb_aux_find_visual_by_id(root, root->root_visual); + assert(visual); + if(argc > 1) + format = parse_format(argv[1]); + if (root->root_depth != 24 || + visual->_class != XCB_VISUAL_CLASS_TRUE_COLOR) + { + printf("Only 24 bit TrueColor visuals for now\n"); + exit(1); + } + depth = format->depth; + + im = create_image(c, depth, format->format); + d = create_window(c, root); + if(format->format == XCB_IMAGE_FORMAT_XY_PIXMAP && depth == 1) + { + w = d; + d = create_pixmap(c, w, depth); + } + dgc = create_gcontext(c, d, root); + if (w) + wgc = create_gcontext(c, w, root); + xcb_flush(c); + + if(im) + { + while((ev = xcb_wait_for_event(c))) + { + if(ev->response_type == XCB_EXPOSE && ((xcb_expose_event_t *) ev)->count == 0) + { + printf("ImagePut sequence %d\n", xcb_image_put(c, d, dgc, im, 0, 0, 0).sequence); + if(w) + { + unsigned int seq; + seq = xcb_copy_plane(c, d, w, wgc, + 0, 0, 0, 0, + WIDTH, HEIGHT, 1).sequence; + printf("CopyPlane sequence %d\n", seq); + } + xcb_flush(c); + } + else if(ev->response_type == 0) + { + xcb_generic_error_t *err = (xcb_generic_error_t *) ev; + printf("Error: %d after sequence %d\n", err->error_code, (unsigned int) err->full_sequence); + } + free(ev); + } + xcb_image_destroy(im); + } + + xcb_disconnect(c); + exit(0); +} diff --git a/image/test_swap.c b/image/test_swap.c new file mode 100644 index 0000000..becf26b --- /dev/null +++ b/image/test_swap.c @@ -0,0 +1,239 @@ +/* + * Copyright © 2008 Keith Packard + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +#include +#include +#include +#include +#include +#include "../aux/xcb_aux.h" +#include "xcb_image.h" + +xcb_image_format_t formats[] = { + XCB_IMAGE_FORMAT_Z_PIXMAP, + XCB_IMAGE_FORMAT_XY_PIXMAP, + XCB_IMAGE_FORMAT_XY_BITMAP, +}; +#define SIZE(a) (sizeof (a) / sizeof (a[0])) +#define NFORMAT SIZE(formats) + +int bpps[] = { + 1, 4, 8, 16, 32 +}; +#define NBPP SIZE(bpps) + +int units[] = { + 8, 16, 32 +}; +#define NUNIT SIZE(units) + +xcb_image_order_t byte_orders[] = { + XCB_IMAGE_ORDER_LSB_FIRST, + XCB_IMAGE_ORDER_MSB_FIRST +}; +#define NBYTE_ORDER SIZE(byte_orders) + +static +uint32_t pixel_mask (int bpp) +{ + if (bpp == 32) + return 0xffffffff; + return (1 << bpp) - 1; +} + +int +compare_image(xcb_image_t *a, xcb_image_t *b) +{ + int x, y; + uint32_t a_pixel, b_pixel; + uint32_t mask = pixel_mask (a->bpp) & pixel_mask (b->bpp); + + for (y = 0; y < a->height; y++) + for (x = 0; x < a->width; x++) { + a_pixel = xcb_image_get_pixel (a, x, y) & mask; + b_pixel = xcb_image_get_pixel (b, x, y) & mask; + if (a_pixel != b_pixel) { + fprintf (stderr, "fail at %d,%d: 0x%x != 0x%x\n", + x, y, a_pixel, b_pixel); + return 0; + } + } + return 1; +} + +#define test_width 63 +#define test_height 2 + +static xcb_image_t * +create_test_image (void) +{ + xcb_image_t *test_image; + int x, y; + uint32_t pixel; + test_image = xcb_image_create(test_width, test_height, + XCB_IMAGE_FORMAT_Z_PIXMAP, + 32, + 32, + 32, + 32, + XCB_IMAGE_ORDER_LSB_FIRST, + XCB_IMAGE_ORDER_LSB_FIRST, + NULL, 0, NULL); + + pixel = 0; + for (y = 0; y < test_height; y++) + for (x = 0; x < test_width; x++) { + xcb_image_put_pixel (test_image, x, y, pixel); + pixel++; + } + return test_image; +} + +static void +convert_test (xcb_image_t *test, xcb_image_t *a) +{ + int x, y; + + for (y = 0; y < test->height; y++) + for (x = 0; x < test->width; x++) + xcb_image_put_pixel (a, x, y, xcb_image_get_pixel (test, x, y)); +} + +static char * +order_name (xcb_image_order_t order) { + if (order == XCB_IMAGE_ORDER_MSB_FIRST) + return "MSB"; + else + return "LSB"; +} + +static void +print_format (xcb_image_t *image) +{ + switch (image->format) { + case XCB_IMAGE_FORMAT_Z_PIXMAP: fprintf (stderr, "Z pixmap"); break; + case XCB_IMAGE_FORMAT_XY_PIXMAP: fprintf (stderr, "XY pixmap"); break; + case XCB_IMAGE_FORMAT_XY_BITMAP: fprintf (stderr, "XY bitmap"); break; + } + fprintf (stderr, " pad: %d bpp: %d depth: %d unit: %d planemask: 0x%08x", + image->scanline_pad, image->bpp, image->depth, image->unit, + image->plane_mask); + fprintf (stderr, " byte order: %s bit order: %s stride: %d\n", + order_name (image->byte_order), order_name (image->bit_order), + image->stride); +} + +int main (int argc, char **argv) { + xcb_image_t *test_image; + xcb_image_t *src_image; + xcb_image_t *dst_image; + int dst_format_i, dst_bpp_i, dst_unit_i, dst_byte_order_i, dst_bit_order_i; + int src_format_i, src_bpp_i, src_unit_i, src_byte_order_i, src_bit_order_i; + xcb_image_format_t dst_format, src_format; + int dst_bpp, src_bpp; + int dst_unit, src_unit; + int dst_byte_order, src_byte_order; + int dst_bit_order, src_bit_order; + + test_image = create_test_image (); + + for (dst_format_i = 0; dst_format_i < NFORMAT; dst_format_i++) { + dst_format = formats[dst_format_i]; + for (src_format_i = 0; src_format_i < NFORMAT; src_format_i++) { + src_format = formats[src_format_i]; + for (dst_bpp_i = 0; dst_bpp_i < NBPP; dst_bpp_i++) { + dst_bpp = bpps[dst_bpp_i]; + for (src_bpp_i = 0; src_bpp_i < NBPP; src_bpp_i++) { + src_bpp = bpps[src_bpp_i]; + for (dst_unit_i = 0; dst_unit_i < NUNIT; dst_unit_i++) { + dst_unit = units[dst_unit_i]; + if (dst_format == XCB_IMAGE_FORMAT_Z_PIXMAP) { + if (dst_bpp == 4 && dst_unit != 8) + continue; + if (dst_bpp > 4 && dst_unit != dst_bpp) + continue; + } + if (dst_format == XCB_IMAGE_FORMAT_XY_BITMAP && dst_bpp != 1) + continue; + for (src_unit_i = 0; src_unit_i < NUNIT; src_unit_i++) { + src_unit = units[src_unit_i]; + if (src_format == XCB_IMAGE_FORMAT_Z_PIXMAP) { + if (src_bpp == 4 && src_unit != 8) + continue; + if (src_bpp > 4 && src_unit != src_bpp) + continue; + } + if (src_format == XCB_IMAGE_FORMAT_XY_BITMAP && src_bpp != 1) + continue; + for (dst_byte_order_i = 0; dst_byte_order_i < NBYTE_ORDER; dst_byte_order_i++) { + dst_byte_order = byte_orders[dst_byte_order_i]; + for (src_byte_order_i = 0; src_byte_order_i < NBYTE_ORDER; src_byte_order_i++) { + src_byte_order = byte_orders[src_byte_order_i]; + for (dst_bit_order_i = 0; dst_bit_order_i < NBYTE_ORDER; dst_bit_order_i++) { + dst_bit_order = byte_orders[dst_bit_order_i]; + if (dst_format == XCB_IMAGE_FORMAT_Z_PIXMAP && dst_bit_order != dst_byte_order) + continue; + for (src_bit_order_i = 0; src_bit_order_i < NBYTE_ORDER; src_bit_order_i++) { + src_bit_order = byte_orders[src_bit_order_i]; + if (src_format == XCB_IMAGE_FORMAT_Z_PIXMAP && src_bit_order != src_byte_order) + continue; + src_image = xcb_image_create (test_width, test_height, src_format, 32, src_bpp, src_bpp, src_unit, + src_byte_order, src_bit_order, NULL, 0, NULL); + dst_image = xcb_image_create (test_width, test_height, dst_format, 32, dst_bpp, dst_bpp, dst_unit, + dst_byte_order, dst_bit_order, NULL, 0, NULL); + convert_test (test_image, src_image); + if (!compare_image (test_image, src_image)) { + fprintf (stderr, "Initialization failure:\n"); + fprintf (stderr, "src format: "); print_format(src_image); + exit (1); + } + xcb_image_convert (src_image, dst_image); + if (!compare_image (src_image, dst_image)) { + /* + * Call the conversion function again so that debugging + * is easier + */ + fprintf (stderr, "Conversion failure:\n"); + fprintf (stderr, "src format: "); print_format(src_image); + fprintf (stderr, "dst format: "); print_format(dst_image); + exit (1); + } + xcb_image_destroy (src_image); + xcb_image_destroy (dst_image); + } + } + } + } + } + } + } + } + } + } + return 0; +} diff --git a/image/test_xcb_image.c b/image/test_xcb_image.c new file mode 100644 index 0000000..ec1c924 --- /dev/null +++ b/image/test_xcb_image.c @@ -0,0 +1,226 @@ +/* + * Copyright © 2008 Bart Massey + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +/* gcc -g -O2 -Wall `pkg-config --cflags --libs xcb` -o test xcb_image.o test_xcb_image.c */ + +#include +#include + +#include + +#include "../aux/xcb_aux.h" +#include "xcb_image.h" + +#define W_W 64 +#define W_H 64 + +void +reflect_window (xcb_connection_t *c, + xcb_drawable_t win, + xcb_drawable_t new_win, + xcb_gcontext_t gc, + uint16_t width, + uint16_t height) +{ + xcb_image_t *image; + uint32_t pixel1; + uint32_t pixel2; + int32_t left_x; + int32_t right_x; + int32_t y; + int format; + + format = XCB_IMAGE_FORMAT_Z_PIXMAP; + + printf ("get_image %d %d\n", width, height); + image = xcb_image_get (c, win, + 0, 0, width, height, + ~0, + format); + + printf ("Create image summary:\n"); + printf (" * format................: %d\n", image->format); + printf (" * byte order............: %d\n", image->byte_order); + printf (" * bitmap order..........: %d\n", image->bit_order); + printf (" * bitmap pad............: %d\n", image->scanline_pad); + printf (" * depth.................: %d\n", image->depth); + printf (" * bytes/line............: %d\n", image->stride); + printf (" * bits/pixel (or unit)..: %d\n", image->bpp); + + printf ("bpl %d %d\n", image->stride, image->height); + + printf("calculating reflection -- this may take awhile...\n"); + + for (left_x = 0 ; left_x < width/2 ; left_x++) + { + for (y = 0 ; y < height ; y++) + { + pixel1 = xcb_image_get_pixel (image, left_x, y); + right_x = width - left_x-1; + if (left_x != right_x) + { + pixel2 = xcb_image_get_pixel (image, right_x, y); + xcb_image_put_pixel (image, left_x, y, pixel2); + } + xcb_image_put_pixel (image, right_x, y, pixel1); + } + } + + printf("putting image\n"); + + xcb_image_put (c, new_win, gc, image, 0, 0, 0); + image = xcb_image_get (c, new_win, + 0, 0, width, height, + ~0, + format); + + printf ("done\n"); +} + +int +main (int argc, char *argv[]) +{ + xcb_connection_t *c; + xcb_screen_t *screen; + xcb_drawable_t win; + xcb_drawable_t new_win; + xcb_drawable_t rect; + xcb_rectangle_t rect_coord = { 0, 0, W_W, W_H}; + xcb_gcontext_t bgcolor, fgcolor; + xcb_point_t points[2]; + uint32_t mask; + uint32_t valgc[2]; + uint32_t valwin[3]; + int depth; + int screen_nbr; + xcb_generic_event_t *e; + + /* Open the connexion to the X server and get the first screen */ + c = xcb_connect (NULL, &screen_nbr); + screen = xcb_aux_get_screen (c, screen_nbr); + depth = xcb_aux_get_depth (c, screen); + + /* Create a black graphic context for drawing in the foreground */ + win = screen->root; + + fgcolor = xcb_generate_id(c); + mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES; + valgc[0] = screen->black_pixel; + valgc[1] = 0; /* no graphics exposures */ + xcb_create_gc(c, fgcolor, win, mask, valgc); + + bgcolor = xcb_generate_id(c); + mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES; + valgc[0] = screen->white_pixel; + valgc[1] = 0; /* no graphics exposures */ + xcb_create_gc(c, bgcolor, win, mask, valgc); + + /* Ask for our window's Id */ + win = xcb_generate_id(c); + + /* Create the window */ + mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE; + valwin[0] = screen->white_pixel; + valwin[1] = XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_EXPOSURE; + valwin[2] = XCB_EVENT_MASK_BUTTON_PRESS; + xcb_create_window (c, /* Connection */ + 0, /* depth */ + win, /* window Id */ + screen->root, /* parent window */ + 0, 0, /* x, y */ + W_W, W_H, /* width, height */ + 10, /* border_width */ + XCB_WINDOW_CLASS_INPUT_OUTPUT,/* class */ + screen->root_visual, /* visual */ + mask, valwin); /* masks, not used yet */ + + /* Map the window on the screen */ + xcb_map_window (c, win); + + /* Create a Pixmap that will fill the window */ + rect = xcb_generate_id (c); + xcb_create_pixmap(c, depth, rect, win, W_W, W_H); + xcb_poly_fill_rectangle(c, rect, bgcolor, 1, &rect_coord); + points[0].x = 0; + points[0].y = 0; + points[1].x = W_W; + points[1].y = W_H; + xcb_poly_line(c, XCB_COORD_MODE_ORIGIN, rect, fgcolor, 2, points); + points[0].x = W_W / 4; + points[0].y = 0; + points[1].x = W_W / 2; + points[1].y = W_H / 2; + xcb_poly_line(c, XCB_COORD_MODE_ORIGIN, rect, fgcolor, 2, points); + + /* Ask for our window's Id */ + new_win = xcb_generate_id(c); + + /* Create the window */ + mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE; + valwin[0] = screen->white_pixel; + valwin[1] = XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_EXPOSURE; + valwin[2] = XCB_EVENT_MASK_BUTTON_PRESS; + xcb_create_window (c, /* Connection */ + 0, /* depth */ + new_win, /* window Id */ + screen->root, /* parent window */ + 0, 0, /* x, y */ + W_W, W_H, /* width, height */ + 10, /* border_width */ + XCB_WINDOW_CLASS_INPUT_OUTPUT,/* class */ + screen->root_visual, /* visual */ + mask, valwin); /* masks, not used yet */ + + + + /* Map the window on the screen */ + xcb_map_window (c, new_win); + + + xcb_flush (c); + + while ((e = xcb_wait_for_event(c))) + { + switch (e->response_type) + { + case XCB_EXPOSE: + { + xcb_copy_area(c, rect, win, bgcolor, + 0, 0, 0, 0, W_W, W_H); + reflect_window (c, win, new_win, + fgcolor, + W_W, W_H); + xcb_flush (c); + break; + } + } + free (e); + } + + return 1; +} diff --git a/image/test_xcb_image_shm.c b/image/test_xcb_image_shm.c new file mode 100644 index 0000000..b68d637 --- /dev/null +++ b/image/test_xcb_image_shm.c @@ -0,0 +1,183 @@ +/* + * Copyright © 2007 Bart Massey + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or their + * institutions shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization from the authors. + */ + +#include +#include + +#include +#include + +#include +#include + +#include "../aux/xcb_aux.h" +#include "xcb_image.h" + +#define W_W 40 +#define W_H 40 + + + +int +main (int argc, char *argv[]) +{ + xcb_connection_t *c; + xcb_screen_t *screen; + xcb_drawable_t win; + xcb_drawable_t rect; + xcb_rectangle_t rect_coord = { 0, 0, W_W, W_H}; + xcb_gcontext_t bgcolor, fgcolor; + xcb_point_t points[2]; + uint32_t mask; + uint32_t valgc[2]; + uint32_t valwin[3]; + int depth; + int screen_nbr; + xcb_generic_event_t *e; + uint8_t format; + + /* Open the connexion to the X server and get the first screen */ + c = xcb_connect (NULL, &screen_nbr); + screen = xcb_aux_get_screen (c, screen_nbr); + depth = xcb_aux_get_depth (c, screen); + + /* Create a black graphic context for drawing in the foreground */ + win = screen->root; + + fgcolor = xcb_generate_id(c); + mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES; + valgc[0] = screen->black_pixel; + valgc[1] = 0; /* no graphics exposures */ + xcb_create_gc(c, fgcolor, win, mask, valgc); + + bgcolor = xcb_generate_id(c); + mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES; + valgc[0] = screen->white_pixel; + valgc[1] = 0; /* no graphics exposures */ + xcb_create_gc(c, bgcolor, win, mask, valgc); + + /* Shm test */ + printf ("shm test begin\n"); + xcb_image_t *img = 0; + xcb_shm_query_version_reply_t *rep; + xcb_shm_segment_info_t shminfo; + + rep = xcb_shm_query_version_reply (c, + xcb_shm_query_version (c), + NULL); + if (!rep || !rep->shared_pixmaps || + rep->major_version < 1 || + (rep->major_version == 1 && rep->minor_version == 0)) + { + printf ("No or insufficient shm support...\n"); + exit (0); + } + format = rep->pixmap_format; + img = xcb_image_create_native (c, W_W, W_H, format, depth, + 0, ~0, 0); + + if (!img) + { + printf ("Can't create image...\n"); + exit (0); + } + + printf ("Create image summary:\n"); + printf (" * format..........: %d\n", img->format); + printf (" * byte order......: %d\n", img->byte_order); + printf (" * bitmap unit.....: %d\n", img->bpp); + printf (" * bitmap order....: %d\n", img->bit_order); + printf (" * bitmap pad......: %d\n", img->scanline_pad); + + shminfo.shmid = shmget (IPC_PRIVATE, img->size, IPC_CREAT|0777); + shminfo.shmaddr = shmat(shminfo.shmid, 0, 0); + img->data = shminfo.shmaddr; + + shminfo.shmseg = xcb_generate_id (c); + xcb_shm_attach(c, shminfo.shmseg, shminfo.shmid, 0); + shmctl(shminfo.shmid, IPC_RMID, 0); + + /* Draw in the image */ + printf ("put the pixel\n"); + xcb_image_put_pixel (img, 20, 20, 65535); + printf ("fin put pixel\n"); + + /* Ask for our window's Id */ + win = xcb_generate_id(c); + + /* Create the window */ + mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE; + valwin[0] = screen->white_pixel; + valwin[1] = XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_EXPOSURE; + valwin[2] = XCB_EVENT_MASK_BUTTON_PRESS; + xcb_create_window (c, /* Connection */ + 0, /* depth */ + win, /* window Id */ + screen->root, /* parent window */ + 0, 0, /* x, y */ + W_W, W_H, /* width, height */ + 10, /* border_width */ + XCB_WINDOW_CLASS_INPUT_OUTPUT,/* class */ + screen->root_visual, /* visual */ + mask, valwin); /* masks, not used yet */ + + /* Map the window on the screen */ + xcb_map_window (c, win); + + /* Create a Pixmap that will fill the window */ + rect = xcb_generate_id (c); + xcb_create_pixmap(c, depth, rect, win, W_W, W_H); + xcb_poly_fill_rectangle(c, rect, bgcolor, 1, &rect_coord); + points[0].x = 0; + points[0].y = 0; + points[1].x = 1; + points[1].y = 1; + xcb_poly_line(c, XCB_COORD_MODE_ORIGIN, rect, fgcolor, 2, points); + + xcb_flush (c); + + while ((e = xcb_wait_for_event(c))) + { + switch (e->response_type) + { + case XCB_EXPOSE: + { + xcb_copy_area(c, rect, win, bgcolor, + 0, 0, 0, 0, W_W, W_H); + printf ("put image\n"); + xcb_image_shm_put (c, win, fgcolor, + img, shminfo, + 0, 0, 0, 0, W_W,W_H, + 0); + xcb_flush (c); + break; + } + } + free (e); + } + + return 1; +} diff --git a/image/xcb-image.pc.in b/image/xcb-image.pc.in new file mode 100644 index 0000000..403fdd0 --- /dev/null +++ b/image/xcb-image.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: XCB Image library +Description: XCB image convenience library +Version: @PACKAGE_VERSION@ +Requires: xcb xcb-shm +Libs: -L${libdir} -lxcb-image @LIBS@ +Cflags: -I${includedir} diff --git a/image/xcb_image.c b/image/xcb_image.c new file mode 100644 index 0000000..413bdc5 --- /dev/null +++ b/image/xcb_image.c @@ -0,0 +1,1009 @@ +/* Copyright © 2007 Bart Massey + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or their + * institutions shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization from the authors. + */ + +#include +#include +#include + +#include +#include +#include "../aux/xcb_aux.h" +#include "../aux/xcb_bitops.h" +#include "xcb_image.h" +#define BUILD +#include "xcb_pixel.h" + + +static xcb_format_t * +find_format_by_depth (const xcb_setup_t *setup, uint8_t depth) +{ + xcb_format_t *fmt = xcb_setup_pixmap_formats(setup); + xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup); + for(; fmt != fmtend; ++fmt) + if(fmt->depth == depth) + return fmt; + return 0; +} + + +static xcb_image_format_t +effective_format(xcb_image_format_t format, uint8_t bpp) +{ + if (format == XCB_IMAGE_FORMAT_Z_PIXMAP && bpp != 1) + return format; + return XCB_IMAGE_FORMAT_XY_PIXMAP; +} + + +static int +format_valid (uint8_t depth, uint8_t bpp, uint8_t unit, + xcb_image_format_t format, uint8_t xpad) +{ + xcb_image_format_t ef = effective_format(format, bpp); + if (depth > bpp) + return 0; + switch(ef) { + case XCB_IMAGE_FORMAT_XY_PIXMAP: + switch(unit) { + case 8: + case 16: + case 32: + break; + default: + return 0; + } + if (xpad < bpp) + return 0; + switch (xpad) { + case 8: + case 16: + case 32: + break; + default: + return 0; + } + break; + case XCB_IMAGE_FORMAT_Z_PIXMAP: + switch (bpp) { + case 4: + if (unit != 8) + return 0; + break; + case 8: + case 16: + case 24: + case 32: + if (unit != bpp) + return 0; + break; + default: + return 0; + } + break; + default: + return 0; + } + return 1; +} + + +static int +image_format_valid (xcb_image_t *image) { + return format_valid(image->depth, + image->bpp, + image->unit, + image->format, + image->scanline_pad); +} + + +void +xcb_image_annotate (xcb_image_t *image) +{ + xcb_image_format_t ef = effective_format(image->format, image->bpp); + switch (ef) { + case XCB_IMAGE_FORMAT_XY_PIXMAP: + image->stride = xcb_roundup(image->width, image->scanline_pad) >> 3; + image->size = image->height * image->stride * image->depth; + break; + case XCB_IMAGE_FORMAT_Z_PIXMAP: + image->stride = xcb_roundup((uint32_t)image->width * + (uint32_t)image->bpp, + image->scanline_pad) >> 3; + image->size = image->height * image->stride; + break; + default: + assert(0); + } +} + + +xcb_image_t * +xcb_image_create_native (xcb_connection_t * c, + uint16_t width, + uint16_t height, + xcb_image_format_t format, + uint8_t depth, + void * base, + uint32_t bytes, + uint8_t * data) +{ + const xcb_setup_t * setup = xcb_get_setup(c); + xcb_format_t * fmt; + xcb_image_format_t ef = format; + + if (ef == XCB_IMAGE_FORMAT_Z_PIXMAP && depth == 1) + ef = XCB_IMAGE_FORMAT_XY_PIXMAP; + switch (ef) { + case XCB_IMAGE_FORMAT_XY_BITMAP: + if (depth != 1) + return 0; + /* fall through */ + case XCB_IMAGE_FORMAT_XY_PIXMAP: + if (depth > 1) { + fmt = find_format_by_depth(setup, depth); + if (!fmt) + return 0; + } + return xcb_image_create(width, height, format, + setup->bitmap_format_scanline_pad, + depth, depth, setup->bitmap_format_scanline_unit, + setup->image_byte_order, + setup->bitmap_format_bit_order, + base, bytes, data); + case XCB_IMAGE_FORMAT_Z_PIXMAP: + fmt = find_format_by_depth(setup, depth); + if (!fmt) + return 0; + return xcb_image_create(width, height, format, + fmt->scanline_pad, + fmt->depth, fmt->bits_per_pixel, 0, + setup->image_byte_order, + XCB_IMAGE_ORDER_MSB_FIRST, + base, bytes, data); + default: + assert(0); + } + assert(0); +} + + +xcb_image_t * +xcb_image_create (uint16_t width, + uint16_t height, + xcb_image_format_t format, + uint8_t xpad, + uint8_t depth, + uint8_t bpp, + uint8_t unit, + xcb_image_order_t byte_order, + xcb_image_order_t bit_order, + void * base, + uint32_t bytes, + uint8_t * data) +{ + xcb_image_t * image; + + if (unit == 0) { + switch (format) { + case XCB_IMAGE_FORMAT_XY_BITMAP: + case XCB_IMAGE_FORMAT_XY_PIXMAP: + unit = 32; + break; + case XCB_IMAGE_FORMAT_Z_PIXMAP: + if (bpp == 1) { + unit = 32; + break; + } + if (bpp < 8) { + unit = 8; + break; + } + unit = bpp; + break; + } + } + if (!format_valid(depth, bpp, unit, format, xpad)) + return 0; + image = malloc(sizeof(*image)); + if (image == 0) + return 0; + image->width = width; + image->height = height; + image->format = format; + image->scanline_pad = xpad; + image->depth = depth; + image->bpp = bpp; + image->unit = unit; + image->plane_mask = xcb_mask(depth); + image->byte_order = byte_order; + image->bit_order = bit_order; + xcb_image_annotate(image); + + /* + * Ways this function can be called: + * * with data: we fail if bytes isn't + * large enough, else leave well enough alone. + * * with base and !data: if bytes is zero, we + * default; otherwise we fail if bytes isn't + * large enough, else fill in data + * * with !base and !data: we malloc storage + * for the data, save that address as the base, + * and fail if malloc does. + * + * When successful, we establish the invariant that data + * points at sufficient storage that may have been + * supplied, and base is set iff it should be + * auto-freed when the image is destroyed. + * + * Except as a special case when base = 0 && data == 0 && + * bytes == ~0 we just return the image structure and let + * the caller deal with getting the allocation right. + */ + if (!base && !data && bytes == ~0) { + image->base = 0; + image->data = 0; + return image; + } + if (!base && data && bytes == 0) + bytes = image->size; + image->base = base; + image->data = data; + if (!image->data) { + if (image->base) { + image->data = image->base; + } else { + bytes = image->size; + image->base = malloc(bytes); + image->data = image->base; + } + } + if (!image->data || bytes < image->size) { + free(image); + return 0; + } + return image; +} + + +void +xcb_image_destroy (xcb_image_t *image) +{ + if (image->base) + free (image->base); + free (image); +} + + +xcb_image_t * +xcb_image_get (xcb_connection_t * conn, + xcb_drawable_t draw, + int16_t x, + int16_t y, + uint16_t width, + uint16_t height, + uint32_t plane_mask, + xcb_image_format_t format) +{ + xcb_get_image_cookie_t image_cookie; + xcb_get_image_reply_t * imrep; + xcb_image_t * image = 0; + uint32_t bytes; + uint8_t * data; + + image_cookie = xcb_get_image(conn, format, draw, x, y, + width, height, plane_mask); + imrep = xcb_get_image_reply(conn, image_cookie, 0); + if (!imrep) + return 0; + bytes = xcb_get_image_data_length(imrep); + data = xcb_get_image_data(imrep); + switch (format) { + case XCB_IMAGE_FORMAT_XY_PIXMAP: + plane_mask &= xcb_mask(imrep->depth); + if (plane_mask != xcb_mask(imrep->depth)) { + xcb_image_t * tmp_image = + xcb_image_create_native(conn, width, height, format, + imrep->depth, 0, 0, 0); + int i; + uint32_t rpm = plane_mask; + uint8_t * src_plane = image->data; + uint8_t * dst_plane = tmp_image->data; + uint32_t size = image->height * image->stride; + + if (!tmp_image) { + free(imrep); + return 0; + } + if (tmp_image->bit_order == XCB_IMAGE_ORDER_MSB_FIRST) + rpm = xcb_bit_reverse(plane_mask, imrep->depth); + for (i = 0; i < imrep->depth; i++) { + if (rpm & 1) { + memcpy(dst_plane, src_plane, size); + src_plane += size; + } else { + memset(dst_plane, 0, size); + } + dst_plane += size; + } + tmp_image->plane_mask = plane_mask; + image = tmp_image; + free(imrep); + break; + } + /* fall through */ + case XCB_IMAGE_FORMAT_Z_PIXMAP: + image = xcb_image_create_native(conn, width, height, format, + imrep->depth, imrep, bytes, data); + if (!image) { + free(imrep); + return 0; + } + break; + default: + assert(0); + } + assert(bytes == image->size); + return image; +} + + +xcb_image_t * +xcb_image_native (xcb_connection_t * c, + xcb_image_t * image, + int convert) +{ + xcb_image_t * tmp_image = 0; + const xcb_setup_t * setup = xcb_get_setup(c); + xcb_format_t * fmt = 0; + xcb_image_format_t ef = effective_format(image->format, image->bpp); + uint8_t bpp = 1; + + if (image->depth > 1 || ef == XCB_IMAGE_FORMAT_Z_PIXMAP) { + fmt = find_format_by_depth(setup, image->depth); + /* XXX For now, we don't do depth conversions, even + for xy-pixmaps */ + if (!fmt) + return 0; + bpp = fmt->bits_per_pixel; + } + switch (ef) { + case XCB_IMAGE_FORMAT_XY_PIXMAP: + if (setup->bitmap_format_scanline_unit != image->unit || + setup->bitmap_format_scanline_pad != image->scanline_pad || + setup->image_byte_order != image->byte_order || + setup->bitmap_format_bit_order != image->bit_order || + bpp != image->bpp) { + if (!convert) + return 0; + tmp_image = + xcb_image_create(image->width, image->height, image->format, + setup->bitmap_format_scanline_pad, + image->depth, bpp, + setup->bitmap_format_scanline_unit, + setup->image_byte_order, + setup->bitmap_format_bit_order, + 0, 0, 0); + if (!tmp_image) + return 0; + } + break; + case XCB_IMAGE_FORMAT_Z_PIXMAP: + if (fmt->scanline_pad != image->scanline_pad || + setup->image_byte_order != image->byte_order || + bpp != image->bpp) { + if (!convert) + return 0; + tmp_image = + xcb_image_create(image->width, image->height, image->format, + fmt->scanline_pad, + image->depth, bpp, 0, + setup->image_byte_order, + XCB_IMAGE_ORDER_MSB_FIRST, + 0, 0, 0); + if (!tmp_image) + return 0; + } + break; + default: + assert(0); + } + if (tmp_image) { + if (!xcb_image_convert(image, tmp_image)) { + xcb_image_destroy(tmp_image); + return 0; + } + image = tmp_image; + } + return image; +} + + +xcb_void_cookie_t +xcb_image_put (xcb_connection_t * conn, + xcb_drawable_t draw, + xcb_gcontext_t gc, + xcb_image_t * image, + int16_t x, + int16_t y, + uint8_t left_pad) +{ + return xcb_put_image(conn, image->format, draw, gc, + image->width, image->height, + x, y, left_pad, + image->depth, + image->size, + image->data); +} + + + +/* + * Shm stuff + */ + +xcb_image_t * +xcb_image_shm_put (xcb_connection_t * conn, + xcb_drawable_t draw, + xcb_gcontext_t gc, + xcb_image_t * image, + xcb_shm_segment_info_t shminfo, + int16_t src_x, + int16_t src_y, + int16_t dest_x, + int16_t dest_y, + uint16_t src_width, + uint16_t src_height, + uint8_t send_event) +{ + if (!xcb_image_native(conn, image, 0)) + return 0; + if (!shminfo.shmaddr) + return 0; + xcb_shm_put_image(conn, draw, gc, + image->width, image->height, + src_x, src_y, src_width, src_height, + dest_x, dest_y, + image->depth, image->format, + send_event, + shminfo.shmseg, + image->data - shminfo.shmaddr); + return image; +} + + +int +xcb_image_shm_get (xcb_connection_t * conn, + xcb_drawable_t draw, + xcb_image_t * image, + xcb_shm_segment_info_t shminfo, + int16_t x, + int16_t y, + uint32_t plane_mask) +{ + xcb_shm_get_image_reply_t * setup; + xcb_shm_get_image_cookie_t cookie; + xcb_generic_error_t * err = 0; + + if (!shminfo.shmaddr) + return 0; + cookie = xcb_shm_get_image(conn, draw, + x, y, + image->width, image->height, + plane_mask, + image->format, + shminfo.shmseg, + image->data - shminfo.shmaddr); + setup = xcb_shm_get_image_reply(conn, cookie, &err); + if (err) { + fprintf(stderr, "ShmGetImageReply error %d\n", (int)err->error_code); + free(err); + return 0; + } else { + free (setup); + return 1; + } +} + + +static uint32_t +xy_image_byte (xcb_image_t *image, uint32_t x) +{ + x >>= 3; + if (image->byte_order == image->bit_order) + return x; + switch (image->unit) { + default: + case 8: + return x; + case 16: + return x ^ 1; + case 32: + return x ^ 3; + } +} + +static uint32_t +xy_image_bit (xcb_image_t *image, uint32_t x) +{ + x &= 7; + if (image->bit_order == XCB_IMAGE_ORDER_MSB_FIRST) + x = 7 - x; + return x; +} + +/* GetPixel/PutPixel */ + +/* XXX this is the most hideously done cut-and-paste + to below. Any bugs fixed there should be fixed here + and vice versa. */ +void +xcb_image_put_pixel (xcb_image_t *image, + uint32_t x, + uint32_t y, + uint32_t pixel) +{ + uint8_t *row; + + if (x > image->width || y > image->height) + return; + row = image->data + (y * image->stride); + switch (effective_format(image->format, image->bpp)) { + case XCB_IMAGE_FORMAT_XY_BITMAP: + case XCB_IMAGE_FORMAT_XY_PIXMAP: + /* block */ { + int p; + uint32_t plane_mask = image->plane_mask; + uint8_t * plane = row; + uint32_t byte = xy_image_byte(image, x); + uint32_t bit = xy_image_bit(image,x); + uint8_t mask = 1 << bit; + + for (p = image->bpp - 1; p >= 0; p--) { + if ((plane_mask >> p) & 1) { + uint8_t * bp = plane + byte; + uint8_t this_bit = ((pixel >> p) & 1) << bit; + *bp = (*bp & ~mask) | this_bit; + } + plane += image->stride * image->height; + } + } + break; + case XCB_IMAGE_FORMAT_Z_PIXMAP: + switch (image->bpp) { + uint32_t mask; + case 4: + mask = 0xf; + pixel &= 0xf; + if ((x & 1) == + (image->byte_order == XCB_IMAGE_ORDER_MSB_FIRST)) { + pixel <<= 4; + mask <<= 4; + } + row[x >> 1] = (row[x >> 1] & ~mask) | pixel; + break; + case 8: + row[x] = pixel; + break; + case 16: + switch (image->byte_order) { + case XCB_IMAGE_ORDER_LSB_FIRST: + row[x << 1] = pixel; + row[(x << 1) + 1] = pixel >> 8; + break; + case XCB_IMAGE_ORDER_MSB_FIRST: + row[x << 1] = pixel >> 8; + row[(x << 1) + 1] = pixel; + break; + } + break; + case 24: + switch (image->byte_order) { + case XCB_IMAGE_ORDER_LSB_FIRST: + row[x * 3] = pixel; + row[x * 3 + 1] = pixel >> 8; + row[x * 3 + 2] = pixel >> 16; + break; + case XCB_IMAGE_ORDER_MSB_FIRST: + row[x * 3] = pixel >> 16; + row[x * 3 + 1] = pixel >> 8; + row[x * 3 + 2] = pixel; + break; + } + break; + case 32: + switch (image->byte_order) { + case XCB_IMAGE_ORDER_LSB_FIRST: + row[x << 2] = pixel; + row[(x << 2) + 1] = pixel >> 8; + row[(x << 2) + 2] = pixel >> 16; + row[(x << 2) + 3] = pixel >> 24; + break; + case XCB_IMAGE_ORDER_MSB_FIRST: + row[x << 2] = pixel >> 24; + row[(x << 2) + 1] = pixel >> 16; + row[(x << 2) + 2] = pixel >> 8; + row[(x << 2) + 3] = pixel; + break; + } + break; + default: + assert(0); + } + break; + default: + assert(0); + } +} + + +/* XXX this is the most hideously done cut-and-paste + from above. Any bugs fixed there should be fixed here + and vice versa. */ +uint32_t +xcb_image_get_pixel (xcb_image_t *image, + uint32_t x, + uint32_t y) +{ + uint32_t pixel = 0; + uint8_t *row; + + assert(x < image->width && y < image->height); + row = image->data + (y * image->stride); + switch (effective_format(image->format, image->bpp)) { + case XCB_IMAGE_FORMAT_XY_BITMAP: + case XCB_IMAGE_FORMAT_XY_PIXMAP: + /* block */ { + int p; + uint32_t plane_mask = image->plane_mask; + uint8_t * plane = row; + uint32_t byte = xy_image_byte(image, x); + uint32_t bit = xy_image_bit(image,x); + + for (p = image->bpp - 1; p >= 0; p--) { + pixel <<= 1; + if ((plane_mask >> p) & 1) { + uint8_t * bp = plane + byte; + pixel |= (*bp >> bit) & 1; + } + plane += image->stride * image->height; + } + } + return pixel; + case XCB_IMAGE_FORMAT_Z_PIXMAP: + switch (image->bpp) { + case 4: + if ((x & 1) == (image->byte_order == XCB_IMAGE_ORDER_MSB_FIRST)) + return row[x >> 1] >> 4; + return row[x >> 1] & 0xf; + case 8: + return row[x]; + case 16: + switch (image->byte_order) { + case XCB_IMAGE_ORDER_LSB_FIRST: + pixel = row[x << 1]; + pixel |= row[(x << 1) + 1] << 8; + break; + case XCB_IMAGE_ORDER_MSB_FIRST: + pixel = row[x << 1] << 8; + pixel |= row[(x << 1) + 1]; + break; + } + break; + case 24: + switch (image->byte_order) { + case XCB_IMAGE_ORDER_LSB_FIRST: + pixel = row[x * 3]; + pixel |= row[x * 3 + 1] << 8; + pixel |= row[x * 3 + 2] << 16; + break; + case XCB_IMAGE_ORDER_MSB_FIRST: + pixel = row[x * 3] << 16; + pixel |= row[x * 3 + 1] << 8; + pixel |= row[x * 3 + 2]; + break; + } + break; + case 32: + switch (image->byte_order) { + case XCB_IMAGE_ORDER_LSB_FIRST: + pixel = row[x << 2]; + pixel |= row[(x << 2) + 1] << 8; + pixel |= row[(x << 2) + 2] << 16; + pixel |= row[(x << 2) + 3] << 24; + break; + case XCB_IMAGE_ORDER_MSB_FIRST: + pixel = row[x << 2] << 24; + pixel |= row[(x << 2) + 1] << 16; + pixel |= row[(x << 2) + 2] << 8; + pixel |= row[(x << 2) + 3]; + break; + } + break; + default: + assert(0); + } + return pixel; + default: + assert(0); + } +} + + +xcb_image_t * +xcb_image_create_from_bitmap_data (uint8_t * data, + uint32_t width, + uint32_t height) +{ + return xcb_image_create(width, height, XCB_IMAGE_FORMAT_XY_PIXMAP, + 8, 1, 1, 8, + XCB_IMAGE_ORDER_LSB_FIRST, + XCB_IMAGE_ORDER_LSB_FIRST, + 0, 0, data); +} + + +/* + * (Adapted from libX11.) + * + * xcb_create_pixmap_from_bitmap_data: Routine to make a pixmap of + * given depth from user supplied bitmap data. + * D is any drawable on the same screen that the pixmap will be used in. + * Data is a pointer to the bit data, and + * width & height give the size in bits of the pixmap. + * + * The following format is assumed for data: + * + * format=XY (will use XYPixmap for depth 1 and XYBitmap for larger) + * bit_order=LSBFirst + * padding=8 + * bitmap_unit=8 + */ +xcb_pixmap_t +xcb_create_pixmap_from_bitmap_data (xcb_connection_t * display, + xcb_drawable_t d, + uint8_t * data, + uint32_t width, + uint32_t height, + uint32_t depth, + uint32_t fg, + uint32_t bg, + xcb_gcontext_t * gcp) +{ + xcb_pixmap_t pix; + xcb_image_t * image; + xcb_image_t * final_image; + xcb_gcontext_t gc; + uint32_t mask = 0; + xcb_params_gc_t gcv; + + image = xcb_image_create_from_bitmap_data(data, width, height); + if (!image) + return 0; + if (depth > 1) + image->format = XCB_IMAGE_FORMAT_XY_BITMAP; + final_image = xcb_image_native(display, image, 1); + if (!final_image) { + xcb_image_destroy(image); + return 0; + } + pix = xcb_generate_id(display); + xcb_create_pixmap(display, depth, pix, d, width, height); + gc = xcb_generate_id(display); + XCB_AUX_ADD_PARAM(&mask, &gcv, foreground, fg); + XCB_AUX_ADD_PARAM(&mask, &gcv, background, bg); + xcb_aux_create_gc(display, gc, pix, mask, &gcv); + xcb_image_put(display, pix, gc, final_image, 0, 0, 0); + if (final_image != image) + xcb_image_destroy(final_image); + xcb_image_destroy(image); + if (gcp) + *gcp = gc; + else + xcb_free_gc(display, gc); + return pix; +} + + +/* Thanks to Keith Packard for this code */ +static void +swap_image(uint8_t * src, + uint32_t src_stride, + uint8_t * dst, + uint32_t dst_stride, + uint32_t height, + uint32_t byteswap, + int bitswap, + int nibbleswap) +{ + while (height--) { + uint32_t s; + + for (s = 0; s < src_stride; s++) { + uint8_t b; + uint32_t d = s ^ byteswap; + + if (d > dst_stride) + continue; + + b = src[s]; + if (bitswap) + b = xcb_bit_reverse(b, 8); + if (nibbleswap) + b = (b << 4) | (b >> 4); + dst[d] = b; + } + src += src_stride; + dst += dst_stride; + } +} + +/* Which order are bytes in (low two bits), given + * code which accesses an image one byte at a time + */ +static uint32_t +byte_order(xcb_image_t *i) +{ + uint32_t flip = i->byte_order == XCB_IMAGE_ORDER_MSB_FIRST; + + switch (i->bpp) { + default: + case 8: + return 0; + case 16: + return flip; + case 32: + return flip | (flip << 1); + } +} + +static uint32_t +bit_order(xcb_image_t *i) +{ + uint32_t flip = i->byte_order != i->bit_order; + + switch (i->unit) { + default: + case 8: + return 0; + case 16: + return flip; + case 32: + return flip | (flip << 1); + } +} + +/* Convert from one byte order to another by flipping the + * low two bits of the byte index along a scanline + */ +static uint32_t +conversion_byte_swap(xcb_image_t *src, xcb_image_t *dst) +{ + xcb_image_format_t ef = effective_format(src->format, src->bpp); + + /* src_ef == dst_ef in all callers of this function */ + if (ef == XCB_IMAGE_FORMAT_XY_PIXMAP) { + return bit_order(src) ^ bit_order(dst); + } else { + /* src_bpp == dst_bpp in all callers of this function */ + return byte_order(src) ^ byte_order(dst); + } +} + +xcb_image_t * +xcb_image_convert (xcb_image_t * src, + xcb_image_t * dst) +{ + xcb_image_format_t ef = effective_format(src->format, src->bpp); + + /* Things will go horribly wrong here if a bad + image is passed in, so we check some things + up front just to be nice. */ + assert(image_format_valid(src)); + assert(image_format_valid(dst)); + + /* images must be the same size + * (yes, we could copy a sub-set) + */ + if (src->width != dst->width || + src->height != dst->height) + return 0; + + if (ef == effective_format(dst->format, dst->bpp) && + src->bpp == dst->bpp) + { + if (src->unit == dst->unit && + src->scanline_pad == dst->scanline_pad && + src->byte_order == dst->byte_order && + (ef == XCB_IMAGE_FORMAT_Z_PIXMAP || + src->bit_order == dst->bit_order)) { + memcpy(dst->data, src->data, src->size); + } else { + int bitswap = 0; + int nibbleswap = 0; + uint32_t byteswap = conversion_byte_swap(src, dst); + uint32_t height = src->height;; + + if (ef == XCB_IMAGE_FORMAT_Z_PIXMAP) { + if (src->bpp == 4 && src->byte_order != dst->byte_order) + nibbleswap = 1; + } else { + if (src->bit_order != dst->bit_order) + bitswap = 1; + height *= src->depth; + } + swap_image (src->data, src->stride, dst->data, dst->stride, + height, byteswap, bitswap, nibbleswap); + } + } + else + { + uint32_t x; + uint32_t y; + /* General case: Slow pixel copy. Should we optimize + Z24<->Z32 copies of either endianness? */ + for (y = 0; y < src->height; y++) { + for (x = 0; x < src->width; x++) { + uint32_t pixel = xcb_image_get_pixel(src, x, y); + xcb_image_put_pixel(dst, x, y, pixel); + } + } + } + return dst; +} + +xcb_image_t * +xcb_image_subimage(xcb_image_t * image, + uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height, + void * base, + uint32_t bytes, + uint8_t * data) +{ + int i, j; + xcb_image_t * result; + + if (x + width > image->width) + return 0; + if (y + height > image->height) + return 0; + result = xcb_image_create(width, height, image->format, + image->scanline_pad, image->depth, + image->bpp, image->unit, image->byte_order, + image->bit_order, + base, bytes, data); + if (!result) + return 0; + /* XXX FIXME For now, lose on performance. Sorry. */ + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + uint32_t pixel = xcb_image_get_pixel(image, x + i, y + j); + xcb_image_put_pixel(result, i, j, pixel); + } + } + return result; +} diff --git a/image/xcb_image.h b/image/xcb_image.h new file mode 100644 index 0000000..3b54da3 --- /dev/null +++ b/image/xcb_image.h @@ -0,0 +1,630 @@ +#ifndef __XCB_IMAGE_H__ +#define __XCB_IMAGE_H__ + +/* Copyright (C) 2007 Bart Massey + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or their + * institutions shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization from the authors. + */ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @defgroup xcb__image_t XCB Image Functions + * + * These are functions used to create and manipulate X images. + * + * The X image format we use is specific to this software, + * which is probably a bug; it represents an intermediate + * position between the wire format used by the X GetImage + * and PutImage requests and standard formats like PBM. An + * image consists of a header of type @ref xcb_image_t + * describing the properties of the image, together with a + * pointer to the image data itself. + * + * X wire images come in three formats. An xy-bitmap is a + * bit-packed format that will be expanded to a two-color + * pixmap using a GC when sent over the wire by PutImage. + * An xy-pixmap is one or more bit-planes, each in the same + * format as xy-bitmap. A z-pixmap is a more conventional + * pixmap representation, with each pixel packed into a + * word. Pixmaps are sent and received over the wire only + * to/from drawables of their depth. + * + * Each X server defines, for each depth and format, + * properties of images in that format that are sent and + * received on the wire. We refer to this as a "native" + * image for a given X server. It is not uncommon to want + * to work with non-native images on the client side, or to + * convert between the native images of different servers. + * + * This library provides several things. Facilities for + * creating and destroying images are, of course, provided. + * Wrappers for xcb_get_image() and xcb_put_image() are + * provided; these utilize the image header to simplify the + * interface. Routines for getting and putting image pixels + * are provided: both a generic form that works with + * arbitrary images, and fastpath forms for some common + * cases. Conversion routines are provided for X images; + * these routines have been fairly well optimized for the + * common cases, and should run fast even on older hardware. + * A routine analogous to Xlib's XCreate*FromBitmapData() is + * provided for creating X images from xbm-format data; this + * routine is in this library only because it is a trivial + * use case for the library. + * + * @{ + */ + + +typedef struct xcb_image_t xcb_image_t; + +/** + * @struct xcb_image_t + * A structure that describes an xcb_image_t. + */ +struct xcb_image_t +{ + uint16_t width; /**< Width in pixels, excluding pads etc. */ + uint16_t height; /**< Height in pixels. */ + xcb_image_format_t format; /**< Format. */ + uint8_t scanline_pad; /**< Right pad in bits. Valid pads + * are 8, 16, 32. + */ + uint8_t depth; /**< Depth in bits. Valid depths + * are 1, 4, 8, 16, 24 for z format, + * 1 for xy-bitmap-format, anything + * for xy-pixmap-format. + */ + uint8_t bpp; /**< Storage per pixel in bits. + * Must be >= depth. Valid bpp + * are 1, 4, 8, 16, 24, 32 for z + * format, 1 for xy-bitmap format, + * anything for xy-pixmap-format. + */ + uint8_t unit; /**< Scanline unit in bits for + * xy formats and for bpp == 1, + * in which case valid scanline + * units are 8, 16, 32. Otherwise, + * will be max(8, bpp). Must be >= bpp. + */ + uint32_t plane_mask; /**< When format is + * xy-pixmap and depth > + * 1, this says which + * planes are "valid" in + * some vague sense. + * Currently used only + * by xcb_image_get/put_pixel(), + * and set only by + * xcb_image_get(). + */ + xcb_image_order_t byte_order; /**< Component byte order + * for z-pixmap, byte + * order of scanline unit + * for xy-bitmap and + * xy-pixmap. Nybble + * order for z-pixmap + * when bpp == 4. + */ + xcb_image_order_t bit_order; /**< Bit order of + * scanline unit for + * xy-bitmap and + * xy-pixmap. + */ + uint32_t stride; /**< Bytes per image row. + * Computable from other + * data, but cached for + * convenience/performance. + */ + uint32_t size; /**< Size of image data in bytes. + * Computable from other + * data, but cached for + * convenience/performance. + */ + void * base; /**< Malloced block of storage that + * will be freed by + * @ref xcb_image_destroy() if non-null. + */ + uint8_t * data; /**< The actual image. */ +}; + +typedef struct xcb_shm_segment_info_t xcb_shm_segment_info_t; + +/** + * @struct xcb_shm_segment_info_t + * A structure that stores the informations needed by the MIT Shm + * Extension. + */ +struct xcb_shm_segment_info_t +{ + xcb_shm_seg_t shmseg; + uint32_t shmid; + uint8_t *shmaddr; +}; + + +/** + * Update the cached data of an image. + * @param image The image. + * + * An image's size and stride, among other things, are + * cached in its structure. This function recomputes those + * cached values for the given image. + * @ingroup xcb__image_t + */ +void +xcb_image_annotate (xcb_image_t *image); + +/** + * Create a new image. + * @param width The width of the image, in pixels. + * @param height The height of the image, in pixels. + * @param format The format of the image. + * @param xpad The scanline pad of the image. + * @param depth The depth of the image. + * @param bpp The depth of the image storage. + * @param unit The unit of image representation, in bits. + * @param byte_order The byte order of the image. + * @param bit_order The bit order of the image. + * @param base The base address of malloced image data. + * @param bytes The size in bytes of the storage pointed to by base. + * If base == 0 and bytes == ~0 and data == 0 on + * entry, no storage will be auto-allocated. + * @param data The image data. If data is null and bytes != ~0, then + * an attempt will be made to fill in data; from + * base if it is non-null (and bytes is large enough), else + * by mallocing sufficient storage and filling in base. + * @return The new image. + * + * This function allocates the memory needed for an @ref xcb_image_t structure + * with the given properties. See the description of xcb_image_t for details. + * This function initializes and returns a pointer to the + * xcb_image_t structure. It may try to allocate or reserve data for the + * structure, depending on how @p base, @p bytes and @p data are set. + * + * The image must be destroyed with xcb_image_destroy(). + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_create (uint16_t width, + uint16_t height, + xcb_image_format_t format, + uint8_t xpad, + uint8_t depth, + uint8_t bpp, + uint8_t unit, + xcb_image_order_t byte_order, + xcb_image_order_t bit_order, + void * base, + uint32_t bytes, + uint8_t * data); + + +/** + * Create a new image in connection-native format. + * @param c The connection. + * @param width The width of the image, in pixels. + * @param height The height of the image, in pixels. + * @param format The format of the image. + * @param depth The depth of the image. + * @param base The base address of malloced image data. + * @param bytes The size in bytes of the storage pointed to by base. + * If base == 0 and bytes == ~0 and data == 0 on + * entry, no storage will be auto-allocated. + * @param data The image data. If data is null and bytes != ~0, then + * an attempt will be made to fill in data; from + * base if it is non-null (and bytes is large enough), else + * by mallocing sufficient storage and filling in base. + * @return The new image. + * + * This function calls @ref xcb_image_create() with the given + * properties, and with the remaining properties chosen + * according to the "native format" with the given + * properties on the current connection. + * + * It is usual to use this rather + * than calling xcb_image_create() directly. + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_create_native (xcb_connection_t * c, + uint16_t width, + uint16_t height, + xcb_image_format_t format, + uint8_t depth, + void * base, + uint32_t bytes, + uint8_t * data); + + +/** + * Destroy an image. + * @param image The image to be destroyed. + * + * This function frees the memory associated with the @p image + * parameter. If its base pointer is non-null, it frees + * that also. + * @ingroup xcb__image_t + */ +void +xcb_image_destroy (xcb_image_t *image); + + +/** + * Get an image from the X server. + * @param conn The connection to the X server. + * @param draw The drawable to get the image from. + * @param x The x coordinate in pixels, relative to the origin of the + * drawable and defining the upper-left corner of the rectangle. + * @param y The y coordinate in pixels, relative to the origin of the + * drawable and defining the upper-left corner of the rectangle. + * @param width The width of the subimage in pixels. + * @param height The height of the subimage in pixels. + * @param plane_mask The plane mask. See the protocol document for details. + * @param format The format of the image. + * @return The subimage of @p draw defined by @p x, @p y, @p w, @p h. + * + + * This function returns a new image taken from the + * given drawable @p draw. + * The image will be in connection native format. If the @p format + * is xy-bitmap and the @p plane_mask masks bit planes out, those + * bit planes will be made part of the returned image anyway, + * by zero-filling them; this will require a fresh memory allocation + * and some copying. Otherwise, the resulting image will use the + * xcb_get_image_reply() record as its backing store. + * + * If a problem occurs, the function returns null. + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_get (xcb_connection_t * conn, + xcb_drawable_t draw, + int16_t x, + int16_t y, + uint16_t width, + uint16_t height, + uint32_t plane_mask, + xcb_image_format_t format); + + +/** + * Put an image onto the X server. + * @param conn The connection to the X server. + * @param draw The draw you get the image from. + * @param gc The graphic context. + * @param image The image you want to combine with the rectangle. + * @param x The x coordinate, which is relative to the origin of the + * drawable and defines the x coordinate of the upper-left corner of the + * rectangle. + * @param y The y coordinate, which is relative to the origin of the + * drawable and defines the x coordinate of the upper-left corner of + * the rectangle. + * @param left_pad Notionally shift an xy-bitmap or xy-pixmap image + * to the right some small amount, for some reason. XXX Not clear + * this is currently supported correctly. + * @return The cookie returned by xcb_put_image(). + * + * This function combines an image with a rectangle of the + * specified drawable @p draw. The image must be in native + * format for the connection. The image is drawn at the + * specified location in the drawable. For the xy-bitmap + * format, the foreground pixel in @p gc defines the source + * for the one bits in the image, and the background pixel + * defines the source for the zero bits. For xy-pixmap and + * z-pixmap formats, the depth of the image must match the + * depth of the drawable; the gc is ignored. + * + * @ingroup xcb__image_t + */ +xcb_void_cookie_t +xcb_image_put (xcb_connection_t * conn, + xcb_drawable_t draw, + xcb_gcontext_t gc, + xcb_image_t * image, + int16_t x, + int16_t y, + uint8_t left_pad); + + +/** + * Check image for or convert image to native format. + * @param c The connection to the X server. + * @param image The image. + * @param convert If 0, just check the image for native format. + * Otherwise, actually convert it. + * @return Null if the image is not in native format and can or will not + * be converted. Otherwise, the native format image. + * + * Each X display has its own "native format" for images of a given + * format and depth. This function either checks whether the given + * @p image is in native format for the given connection @p c, or + * actually tries to convert the image to native format, depending + * on whether @p convert is true or false. + * + * When @p convert is true, and the image is not in native format + * but can be converted, it will be, and a pointer to the new image + * will be returned. The image passed in will be unharmed in this + * case; it is the caller's responsibility to check that the returned + * pointer is different and to dispose of the old image if desired. + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_native (xcb_connection_t * c, + xcb_image_t * image, + int convert); + + +/** + * Put a pixel to an image. + * @param image The image. + * @param x The x coordinate of the pixel. + * @param y The y coordinate of the pixel. + * @param pixel The new pixel value. + * + * This function overwrites the pixel in the given @p image with the + * specified @p pixel value (in client format). The image must contain the @p x + * and @p y coordinates, as no clipping is done. This function honors + * the plane-mask for xy-pixmap images. + * @ingroup xcb__image_t + */ +void +xcb_image_put_pixel (xcb_image_t *image, + uint32_t x, + uint32_t y, + uint32_t pixel); + +/** + * Get a pixel from an image. + * @param image The image. + * @param x The x coordinate of the pixel. + * @param y The y coordinate of the pixel. + * @return The pixel value. + * + * This function retrieves a pixel from the given @p image. + * The image must contain the @p x + * and @p y coordinates, as no clipping is done. This function honors + * the plane-mask for xy-pixmap images. + * @ingroup xcb__image_t + */ +uint32_t +xcb_image_get_pixel (xcb_image_t *image, + uint32_t x, + uint32_t y); + + +/** + * Convert an image to a new format. + * @param src Source image. + * @param dst Destination image. + * @return The @p dst image, or null on error. + * + * This function tries to convert the image data of the @p + * src image to the format implied by the @p dst image, + * overwriting the current destination image data. + * The source and destination must have the same + * width, height, and depth. When the source and destination + * are already the same format, a simple copy is done. Otherwise, + * when the destination has the same bits-per-pixel/scanline-unit + * as the source, an optimized copy routine (thanks to Keith Packard) + * is used for the conversion. Otherwise, the copy is done the + * slow, slow way with @ref xcb_image_get_pixel() and + * @ref xcb_image_put_pixel() calls. + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_convert (xcb_image_t * src, + xcb_image_t * dst); + + +/** + * Extract a subimage of an image. + * @param image Source image. + * @param x X coordinate of subimage. + * @param y Y coordinate of subimage. + * @param width Width of subimage. + * @param height Height of subimage. + * @param base Base of memory allocation. + * @param bytes Size of base allocation. + * @param data Memory allocation. + * @return The subimage, or null on error. + * + * Given an image, this function extracts the subimage at the + * given coordinates. The requested subimage must be entirely + * contained in the source @p image. The resulting image will have the same + * general image parameters as the source image. The @p base, @p bytes, + * and @p data arguments are passed to @ref xcb_create_image() unaltered + * to create the destination image---see its documentation for details. + * + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_subimage(xcb_image_t * image, + uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height, + void * base, + uint32_t bytes, + uint8_t * data); + + +/* + * Shm stuff + */ + +/** + * Put the data of an xcb_image_t onto a drawable using the MIT Shm + * Extension. + * @param conn The connection to the X server. + * @param draw The draw you get the image from. + * @param gc The graphic context. + * @param image The image you want to combine with the rectangle. + * @param shminfo A @ref xcb_shm_segment_info_t structure. + * @param src_x The offset in x from the left edge of the image + * defined by the xcb_image_t structure. + * @param src_y The offset in y from the left edge of the image + * defined by the xcb_image_t structure. + * @param dest_x The x coordinate, which is relative to the origin of the + * drawable and defines the x coordinate of the upper-left corner of the + * rectangle. + * @param dest_y The y coordinate, which is relative to the origin of the + * drawable and defines the x coordinate of the upper-left corner of + * the rectangle. + * @param src_width The width of the subimage, in pixels. + * @param src_height The height of the subimage, in pixels. + * @param send_event Indicates whether or not a completion event + * should occur when the image write is complete. + * @return 1 is no problems occurs. + * + * This function combines an image in memory with a shape of the + * specified drawable. The section of the image defined by the @p x, @p y, + * @p width, and @p height arguments is drawn on the specified part of + * the drawable. If XYBitmap format is used, the depth must be + * one, or a``BadMatch'' error results. The foreground pixel in the + * Graphic Context @p gc defines the source for the one bits in the + * image, and the background pixel defines the source for the zero + * bits. For XYPixmap and ZPixmap, the depth must match the depth of + * the drawable, or a ``BadMatch'' error results. + * + * If a problem occurs, the functons returns @c 0. Otherwise, it + * returns @c 1. + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_shm_put (xcb_connection_t * conn, + xcb_drawable_t draw, + xcb_gcontext_t gc, + xcb_image_t * image, + xcb_shm_segment_info_t shminfo, + int16_t src_x, + int16_t src_y, + int16_t dest_x, + int16_t dest_y, + uint16_t src_width, + uint16_t src_height, + uint8_t send_event); + + +/** + * Read image data into a shared memory xcb_image_t. + * @param conn The connection to the X server. + * @param draw The draw you get the image from. + * @param image The image you want to combine with the rectangle. + * @param shminfo A @ref xcb_shm_segment_info_t structure. + * @param x The x coordinate, which are relative to the origin of the + * drawable and define the upper-left corner of the rectangle. + * @param y The y coordinate, which are relative to the origin of the + * drawable and define the upper-left corner of the rectangle. + * @param plane_mask The plane mask. + * @return The subimage of @p draw defined by @p x, @p y, @p w, @p h. + * + * This function reads image data into a shared memory xcb_image_t where + * @p conn is the connection to the X server, @p draw is the source + * drawable, @p image is the destination xcb_image_t, @p x and @p y are offsets + * within the drawable, and @p plane_mask defines which planes are to be + * read. + * + * If a problem occurs, the functons returns @c 0. It returns 1 + * otherwise. + * @ingroup xcb__image_t + */ +int xcb_image_shm_get (xcb_connection_t * conn, + xcb_drawable_t draw, + xcb_image_t * image, + xcb_shm_segment_info_t shminfo, + int16_t x, + int16_t y, + uint32_t plane_mask); + + +/** + * Create an image from user-supplied bitmap data. + * @param data Image data in packed bitmap format. + * @param width Width in bits of image data. + * @param height Height in bits of image data. + * @return The image constructed from the image data, or 0 on error. + * + * This function creates an image from the user-supplied + * bitmap @p data. The bitmap data is assumed to be in + * xbm format (i.e., 8-bit scanline unit, LSB-first, 8-bit pad). + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_create_from_bitmap_data (uint8_t * data, + uint32_t width, + uint32_t height); + +/** + * Create a pixmap from user-supplied bitmap data. + * @param display The connection to the X server. + * @param d The parent drawable for the pixmap. + * @param data Image data in packed bitmap format. + * @param width Width in bits of image data. + * @param height Height in bits of image data. + * @param depth Depth of the desired pixmap. + * @param fg Pixel for one-bits of pixmaps with depth larger than one. + * @param bg Pixel for zero-bits of pixmaps with depth larger than one. + * @param gcp If this pointer is non-null, the GC created to + * fill in the pixmap is stored here; it will have its foreground + * and background set to the supplied value. Otherwise, the GC + * will be freed. + * @return The pixmap constructed from the image data, or 0 on error. + * + * This function creates a pixmap from the user-supplied + * bitmap @p data. The bitmap data is assumed to be in + * xbm format (i.e., 8-bit scanline unit, LSB-first, 8-bit pad). + * If @p depth is greater than 1, the + * bitmap will be expanded to a pixmap using the given + * foreground and background pixels @p fg and @p bg. + * @ingroup xcb__image_t + */ +xcb_pixmap_t +xcb_create_pixmap_from_bitmap_data (xcb_connection_t * display, + xcb_drawable_t d, + uint8_t * data, + uint32_t width, + uint32_t height, + uint32_t depth, + uint32_t fg, + uint32_t bg, + xcb_gcontext_t * gcp); + + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + + +#endif /* __XCB_IMAGE_H__ */ diff --git a/image/xcb_pixel.h b/image/xcb_pixel.h new file mode 100644 index 0000000..fcb22b4 --- /dev/null +++ b/image/xcb_pixel.h @@ -0,0 +1,171 @@ +#ifndef __XCB_PIXEL_H__ +#define __XCB_PIXEL_H__ + +/* Copyright (C) 2007 Bart Massey + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or their + * institutions shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization from the authors. + */ + +#include +#include +#ifndef BUILD +#include +#include +#endif + +/** + * XCB Image fast pixel ops. + * + * Fast inline versions of xcb_image_get_pixel() and + * xcb_image_put_pixel() for various common cases. + * The naming convention is xcb_image_put_pixel_FUB() + * where F is the format and is either XY for bitmaps + * or Z for pixmaps, U is the bitmap unit size or pixmap + * bits-per-pixel, and B is the endianness (if needed) + * and is either M for most-significant-first or L for + * least-significant-first. Note that no checking + * is done on the arguments to these routines---caller beware. + * Also note that the pixel type is chosen to be appropriate + * to the unit; bitmaps use int and pixmaps use the appropriate + * size of unsigned. + * @ingroup xcb__image_t + */ + +_X_INLINE static void +xcb_image_put_pixel_XY32M (xcb_image_t *image, + uint32_t x, + uint32_t y, + int pixel) +{ + uint32_t unit = (x >> 3) & ~xcb_mask(2); + uint32_t byte = xcb_mask(2) - ((x >> 3) & xcb_mask(2)); + uint32_t bit = xcb_mask(3) - (x & xcb_mask(3)); + uint8_t m = 1 << bit; + uint8_t p = pixel << bit; + uint8_t * bp = image->data + (y * image->stride) + (unit | byte); + *bp = (*bp & ~m) | p; +} + +_X_INLINE static void +xcb_image_put_pixel_XY32L (xcb_image_t *image, + uint32_t x, + uint32_t y, + int pixel) +{ + uint32_t bit = x & xcb_mask(3); + uint8_t m = 1 << bit; + uint8_t p = pixel << bit; + uint8_t * bp = image->data + (y * image->stride) + (x >> 3); + *bp = (*bp & ~m) | p; +} + +_X_INLINE static int +xcb_image_get_pixel_XY32M (xcb_image_t *image, + uint32_t x, + uint32_t y) +{ + uint32_t unit = (x >> 3) & ~xcb_mask(2); + uint32_t byte = xcb_mask(2) - ((x >> 3) & xcb_mask(2)); + uint32_t bit = xcb_mask(3) - (x & xcb_mask(3)); + uint8_t * bp = image->data + (y * image->stride) + (unit | byte); + return (*bp >> bit) & 1; +} + +_X_INLINE static int +xcb_image_get_pixel_XY32L (xcb_image_t *image, + uint32_t x, + uint32_t y) +{ + uint32_t bit = x & xcb_mask(3); + uint8_t * bp = image->data + (y * image->stride) + (x >> 3); + return (*bp >> bit) & 1; +} + +_X_INLINE static void +xcb_image_put_pixel_Z8 (xcb_image_t *image, + uint32_t x, + uint32_t y, + uint8_t pixel) +{ + image->data[x + y * image->stride] = pixel; +} + +_X_INLINE static uint8_t +xcb_image_get_pixel_Z8 (xcb_image_t *image, + uint32_t x, + uint32_t y) +{ + return image->data[x + y * image->stride]; +} + +_X_INLINE static void +xcb_image_put_pixel_Z32M (xcb_image_t *image, + uint32_t x, + uint32_t y, + uint32_t pixel) +{ + uint8_t * row = image->data + (y * image->stride); + row[x << 2] = pixel >> 24; + row[(x << 2) + 1] = pixel >> 16; + row[(x << 2) + 2] = pixel >> 8; + row[(x << 2) + 3] = pixel; +} + +_X_INLINE static void +xcb_image_put_pixel_Z32L (xcb_image_t *image, + uint32_t x, + uint32_t y, + uint32_t pixel) +{ + uint8_t * row = image->data + (y * image->stride); + row[x << 2] = pixel; + row[(x << 2) + 1] = pixel >> 8; + row[(x << 2) + 2] = pixel >> 16; + row[(x << 2) + 3] = pixel >> 24; +} + +_X_INLINE static uint32_t +xcb_image_get_pixel_Z32M (xcb_image_t *image, + uint32_t x, + uint32_t y) +{ + uint8_t * row = image->data + (y * image->stride); + uint32_t pixel = row[x << 2] << 24; + pixel |= row[(x << 2) + 1] << 16; + pixel |= row[(x << 2) + 2] << 8; + return pixel | row[(x << 2) + 3]; +} + +_X_INLINE static uint32_t +xcb_image_get_pixel_Z32L (xcb_image_t *image, + uint32_t x, + uint32_t y) +{ + uint8_t * row = image->data + (y * image->stride); + uint32_t pixel = row[x << 2]; + pixel |= row[(x << 2) + 1] << 8; + pixel |= row[(x << 2) + 2] << 16; + return pixel | row[(x << 2) + 3] << 24; +} + +#endif /* __XCB_PIXEL_H__ */ diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..6781b98 --- /dev/null +++ b/install-sh @@ -0,0 +1,520 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2009-04-28.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/keysyms/Makefile.am b/keysyms/Makefile.am new file mode 100644 index 0000000..f7965ab --- /dev/null +++ b/keysyms/Makefile.am @@ -0,0 +1,17 @@ + +MAINTAINERCLEANFILES = Makefile.in + +lib_LTLIBRARIES = libxcb-keysyms.la + +xcbinclude_HEADERS = xcb_keysyms.h + +AM_CFLAGS = $(CWARNFLAGS) + +libxcb_keysyms_la_SOURCES = keysyms.c +libxcb_keysyms_la_CPPFLAGS = $(XCB_CFLAGS) +libxcb_keysyms_la_LIBADD = $(XCB_LIBS) +libxcb_keysyms_la_LDFLAGS = -version-info 1:0:0 + +pkgconfig_DATA = xcb-keysyms.pc + +EXTRA_DIST=xcb-keysyms.pc.in diff --git a/keysyms/keysyms.c b/keysyms/keysyms.c new file mode 100644 index 0000000..c3e7f2e --- /dev/null +++ b/keysyms/keysyms.c @@ -0,0 +1,487 @@ +/* + * Copyright © 2008 Ian Osgood + * Copyright © 2008 Jamey Sharp + * Copyright © 2008 Josh Triplett + * Copyright © 2008 Ulrich Eckhardt + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +#include + +#include +#define XK_MISCELLANY +#define XK_XKB_KEYS +#define XK_LATIN1 +#define XK_LATIN2 +#define XK_LATIN3 +#define XK_LATIN4 +#define XK_CYRILLIC +#define XK_GREEK +#define XK_ARMENIAN +#include + +#include "xcb_keysyms.h" + +/* Private declaration */ +enum tag_t { + TAG_COOKIE, + TAG_VALUE +}; + +struct _XCBKeySymbols +{ + xcb_connection_t *c; + enum tag_t tag; + union { + xcb_get_keyboard_mapping_cookie_t cookie; + xcb_get_keyboard_mapping_reply_t *reply; + } u; +}; + +static void xcb_convert_case(xcb_keysym_t sym, + xcb_keysym_t *lower, + xcb_keysym_t *upper); + +static void xcb_key_symbols_get_reply (xcb_key_symbols_t *syms, + xcb_generic_error_t **e); + +/* public implementation */ + +xcb_key_symbols_t * +xcb_key_symbols_alloc (xcb_connection_t *c) +{ + xcb_key_symbols_t *syms; + xcb_keycode_t min_keycode; + xcb_keycode_t max_keycode; + + if (!c) + return NULL; + + syms = malloc (sizeof (xcb_key_symbols_t)); + + syms->c = c; + syms->tag = TAG_COOKIE; + + min_keycode = xcb_get_setup (c)->min_keycode; + max_keycode = xcb_get_setup (c)->max_keycode; + + syms->u.cookie = xcb_get_keyboard_mapping(c, + min_keycode, + max_keycode - min_keycode + 1); + + return syms; +} + +void +xcb_key_symbols_free (xcb_key_symbols_t *syms) +{ + if (syms) + { + if (syms->tag == TAG_VALUE) + free (syms->u.reply); + free (syms); + syms = NULL; + } +} + +/* Use of the 'col' parameter: + +A list of KeySyms is associated with each KeyCode. The list is intended +to convey the set of symbols on the corresponding key. If the list +(ignoring trailing NoSymbol entries) is a single KeySym ``K'', then the +list is treated as if it were the list ``K NoSymbol K NoSymbol''. If the +list (ignoring trailing NoSymbol entries) is a pair of KeySyms ``K1 +K2'', then the list is treated as if it were the list ``K1 K2 K1 K2''. +If the list (ignoring trailing NoSymbol entries) is a triple of KeySyms +``K1 K2 K3'', then the list is treated as if it were the list ``K1 K2 K3 +NoSymbol''. When an explicit ``void'' element is desired in the list, +the value VoidSymbol can be used. + +The first four elements of the list are split into two groups of +KeySyms. Group 1 contains the first and second KeySyms; Group 2 contains +the third and fourth KeySyms. Within each group, if the second element +of the group is NoSymbol , then the group should be treated as if the +second element were the same as the first element, except when the first +element is an alphabetic KeySym ``K'' for which both lowercase and +uppercase forms are defined. In that case, the group should be treated +as if the first element were the lowercase form of ``K'' and the second +element were the uppercase form of ``K.'' + +The standard rules for obtaining a KeySym from a KeyPress event make use +of only the Group 1 and Group 2 KeySyms; no interpretation of other +KeySyms in the list is given. Which group to use is determined by the +modifier state. Switching between groups is controlled by the KeySym +named MODE SWITCH, by attaching that KeySym to some KeyCode and +attaching that KeyCode to any one of the modifiers Mod1 through Mod5. +This modifier is called the group modifier. For any KeyCode, Group 1 is +used when the group modifier is off, and Group 2 is used when the group +modifier is on. + +The Lock modifier is interpreted as CapsLock when the KeySym named +XK_Caps_Lock is attached to some KeyCode and that KeyCode is attached to +the Lock modifier. The Lock modifier is interpreted as ShiftLock when +the KeySym named XK_Shift_Lock is attached to some KeyCode and that +KeyCode is attached to the Lock modifier. If the Lock modifier could be +interpreted as both CapsLock and ShiftLock, the CapsLock interpretation +is used. + +The operation of keypad keys is controlled by the KeySym named +XK_Num_Lock, by attaching that KeySym to some KeyCode and attaching that +KeyCode to any one of the modifiers Mod1 through Mod5 . This modifier is +called the numlock modifier. The standard KeySyms with the prefix +``XK_KP_'' in their name are called keypad KeySyms; these are KeySyms +with numeric value in the hexadecimal range 0xFF80 to 0xFFBD inclusive. +In addition, vendor-specific KeySyms in the hexadecimal range 0x11000000 +to 0x1100FFFF are also keypad KeySyms. + +Within a group, the choice of KeySym is determined by applying the first +rule that is satisfied from the following list: + +* The numlock modifier is on and the second KeySym is a keypad KeySym. In + this case, if the Shift modifier is on, or if the Lock modifier is on + and is interpreted as ShiftLock, then the first KeySym is used, + otherwise the second KeySym is used. + +* The Shift and Lock modifiers are both off. In this case, the first + KeySym is used. + +* The Shift modifier is off, and the Lock modifier is on and is + interpreted as CapsLock. In this case, the first KeySym is used, but + if that KeySym is lowercase alphabetic, then the corresponding + uppercase KeySym is used instead. + +* The Shift modifier is on, and the Lock modifier is on and is + interpreted as CapsLock. In this case, the second KeySym is used, but + if that KeySym is lowercase alphabetic, then the corresponding + uppercase KeySym is used instead. + +* The Shift modifier is on, or the Lock modifier is on and is + interpreted as ShiftLock, or both. In this case, the second KeySym is + used. + +*/ + +xcb_keysym_t xcb_key_symbols_get_keysym (xcb_key_symbols_t *syms, + xcb_keycode_t keycode, + int col) +{ + xcb_keysym_t *keysyms; + xcb_keysym_t keysym_null = { XCB_NO_SYMBOL }; + xcb_keysym_t lsym; + xcb_keysym_t usym; + xcb_keycode_t min_keycode; + xcb_keycode_t max_keycode; + int per; + + if (!syms) + return keysym_null; + + xcb_key_symbols_get_reply (syms, NULL); + + keysyms = xcb_get_keyboard_mapping_keysyms (syms->u.reply); + min_keycode = xcb_get_setup (syms->c)->min_keycode; + max_keycode = xcb_get_setup (syms->c)->max_keycode; + + per = syms->u.reply->keysyms_per_keycode; + if ((col < 0) || ((col >= per) && (col > 3)) || + (keycode < min_keycode) || + (keycode > max_keycode)) + return keysym_null; + + keysyms = &keysyms[(keycode - min_keycode) * per]; + if (col < 4) + { + if (col > 1) + { + while ((per > 2) && (keysyms[per - 1] == XCB_NO_SYMBOL)) + per--; + if (per < 3) + col -= 2; + } + if ((per <= (col|1)) || (keysyms[col|1] == XCB_NO_SYMBOL)) + { + xcb_convert_case(keysyms[col&~1], &lsym, &usym); + if (!(col & 1)) + return lsym; + else if (usym == lsym) + return keysym_null; + else + return usym; + } + } + return keysyms[col]; +} + +xcb_keycode_t * +xcb_key_symbols_get_keycode(xcb_key_symbols_t *syms, + xcb_keysym_t keysym) +{ + xcb_keysym_t ks; + int j, nresult = 0; + xcb_keycode_t i, min, max, *result = NULL; + + if(syms) + { + xcb_key_symbols_get_reply (syms, NULL); + min = xcb_get_setup(syms->c)->min_keycode; + max = xcb_get_setup(syms->c)->max_keycode; + + for(j = 0; j < syms->u.reply->keysyms_per_keycode; j++) + for(i = min; i && i <= max; i++) + { + ks = xcb_key_symbols_get_keysym(syms, i, j); + if(ks == keysym) + { + nresult++; + result = realloc(result, sizeof(xcb_keycode_t) * (nresult + 1)); + result[nresult - 1] = i; + result[nresult] = XCB_NO_SYMBOL; + } + } + } + + return result; +} + +xcb_keysym_t +xcb_key_press_lookup_keysym (xcb_key_symbols_t *syms, + xcb_key_press_event_t *event, + int col) +{ + return xcb_key_symbols_get_keysym (syms, event->detail, col); +} + +xcb_keysym_t +xcb_key_release_lookup_keysym (xcb_key_symbols_t *syms, + xcb_key_release_event_t *event, + int col) +{ + return xcb_key_symbols_get_keysym (syms, event->detail, col); +} + +int +xcb_refresh_keyboard_mapping (xcb_key_symbols_t *syms, + xcb_mapping_notify_event_t *event) +{ + if (event->request == XCB_MAPPING_KEYBOARD && syms) { + if (syms->tag == TAG_VALUE) { + xcb_keycode_t min_keycode; + xcb_keycode_t max_keycode; + + if (syms->u.reply) { + free (syms->u.reply); + syms->u.reply = NULL; + } + syms->tag = TAG_COOKIE; + min_keycode = xcb_get_setup (syms->c)->min_keycode; + max_keycode = xcb_get_setup (syms->c)->max_keycode; + + syms->u.cookie = xcb_get_keyboard_mapping(syms->c, + min_keycode, + max_keycode - min_keycode + 1); + + } + return 1; + } + return 0; +} + + +/* Tests for classes of symbols */ + +int +xcb_is_keypad_key (xcb_keysym_t keysym) +{ + return ((keysym >= XK_KP_Space) && (keysym <= XK_KP_Equal)); +} + +int +xcb_is_private_keypad_key (xcb_keysym_t keysym) +{ + return ((keysym >= 0x11000000) && (keysym <= 0x1100FFFF)); +} + +int +xcb_is_cursor_key (xcb_keysym_t keysym) +{ + return ((keysym >= XK_Home) && (keysym <= XK_Select)); +} + +int +xcb_is_pf_key (xcb_keysym_t keysym) +{ + return ((keysym >= XK_KP_F1) && (keysym <= XK_KP_F4)); +} + +int +xcb_is_function_key (xcb_keysym_t keysym) +{ + return ((keysym >= XK_F1) && (keysym <= XK_F35)); +} + +int +xcb_is_misc_function_key (xcb_keysym_t keysym) +{ + return ((keysym >= XK_Select) && (keysym <= XK_Break)); +} + +int +xcb_is_modifier_key (xcb_keysym_t keysym) +{ + return (((keysym >= XK_Shift_L) && (keysym <= XK_Hyper_R)) || + ((keysym >= XK_ISO_Lock) && (keysym <= XK_ISO_Last_Group_Lock)) || + (keysym == XK_Mode_switch) || + (keysym == XK_Num_Lock)); +} + +/* private functions */ + +void +xcb_convert_case(xcb_keysym_t sym, + xcb_keysym_t *lower, + xcb_keysym_t *upper) +{ + *lower = sym; + *upper = sym; + + switch(sym >> 8) + { + case 0: /* Latin 1 */ + if ((sym >= XK_A) && (sym <= XK_Z)) + *lower += (XK_a - XK_A); + else if ((sym >= XK_a) && (sym <= XK_z)) + *upper -= (XK_a - XK_A); + else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis)) + *lower += (XK_agrave - XK_Agrave); + else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis)) + *upper -= (XK_agrave - XK_Agrave); + else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn)) + *lower += (XK_oslash - XK_Ooblique); + else if ((sym >= XK_oslash) && (sym <= XK_thorn)) + *upper -= (XK_oslash - XK_Ooblique); + break; + case 1: /* Latin 2 */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (sym == XK_Aogonek) + *lower = XK_aogonek; + else if (sym >= XK_Lstroke && sym <= XK_Sacute) + *lower += (XK_lstroke - XK_Lstroke); + else if (sym >= XK_Scaron && sym <= XK_Zacute) + *lower += (XK_scaron - XK_Scaron); + else if (sym >= XK_Zcaron && sym <= XK_Zabovedot) + *lower += (XK_zcaron - XK_Zcaron); + else if (sym == XK_aogonek) + *upper = XK_Aogonek; + else if (sym >= XK_lstroke && sym <= XK_sacute) + *upper -= (XK_lstroke - XK_Lstroke); + else if (sym >= XK_scaron && sym <= XK_zacute) + *upper -= (XK_scaron - XK_Scaron); + else if (sym >= XK_zcaron && sym <= XK_zabovedot) + *upper -= (XK_zcaron - XK_Zcaron); + else if (sym >= XK_Racute && sym <= XK_Tcedilla) + *lower += (XK_racute - XK_Racute); + else if (sym >= XK_racute && sym <= XK_tcedilla) + *upper -= (XK_racute - XK_Racute); + break; + case 2: /* Latin 3 */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (sym >= XK_Hstroke && sym <= XK_Hcircumflex) + *lower += (XK_hstroke - XK_Hstroke); + else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex) + *lower += (XK_gbreve - XK_Gbreve); + else if (sym >= XK_hstroke && sym <= XK_hcircumflex) + *upper -= (XK_hstroke - XK_Hstroke); + else if (sym >= XK_gbreve && sym <= XK_jcircumflex) + *upper -= (XK_gbreve - XK_Gbreve); + else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex) + *lower += (XK_cabovedot - XK_Cabovedot); + else if (sym >= XK_cabovedot && sym <= XK_scircumflex) + *upper -= (XK_cabovedot - XK_Cabovedot); + break; + case 3: /* Latin 4 */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (sym >= XK_Rcedilla && sym <= XK_Tslash) + *lower += (XK_rcedilla - XK_Rcedilla); + else if (sym >= XK_rcedilla && sym <= XK_tslash) + *upper -= (XK_rcedilla - XK_Rcedilla); + else if (sym == XK_ENG) + *lower = XK_eng; + else if (sym == XK_eng) + *upper = XK_ENG; + else if (sym >= XK_Amacron && sym <= XK_Umacron) + *lower += (XK_amacron - XK_Amacron); + else if (sym >= XK_amacron && sym <= XK_umacron) + *upper -= (XK_amacron - XK_Amacron); + break; + case 6: /* Cyrillic */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE) + *lower -= (XK_Serbian_DJE - XK_Serbian_dje); + else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze) + *upper += (XK_Serbian_DJE - XK_Serbian_dje); + else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN) + *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu); + else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign) + *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu); + break; + case 7: /* Greek */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent) + *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent); + else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent && + sym != XK_Greek_iotaaccentdieresis && + sym != XK_Greek_upsilonaccentdieresis) + *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent); + else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA) + *lower += (XK_Greek_alpha - XK_Greek_ALPHA); + else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega && + sym != XK_Greek_finalsmallsigma) + *upper -= (XK_Greek_alpha - XK_Greek_ALPHA); + break; + case 0x14: /* Armenian */ + if (sym >= XK_Armenian_AYB && sym <= XK_Armenian_fe) { + *lower = sym | 1; + *upper = sym & ~1; + } + break; + } +} + +void +xcb_key_symbols_get_reply (xcb_key_symbols_t *syms, + xcb_generic_error_t **e) +{ + if (!syms) + return; + + if (syms->tag == TAG_COOKIE) + { + syms->tag = TAG_VALUE; + syms->u.reply = xcb_get_keyboard_mapping_reply(syms->c, + syms->u.cookie, + e); + } +} diff --git a/keysyms/xcb-keysyms.pc.in b/keysyms/xcb-keysyms.pc.in new file mode 100644 index 0000000..249fdc0 --- /dev/null +++ b/keysyms/xcb-keysyms.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: XCB Keysyms library +Description: XCB Keysyms +Version: @PACKAGE_VERSION@ +Requires: xcb +Libs: -L${libdir} -lxcb-keysyms @LIBS@ +Cflags: -I${includedir} diff --git a/keysyms/xcb_keysyms.h b/keysyms/xcb_keysyms.h new file mode 100644 index 0000000..9d34a50 --- /dev/null +++ b/keysyms/xcb_keysyms.h @@ -0,0 +1,71 @@ +#ifndef __XCB_KEYSYMS_H__ +#define __XCB_KEYSYMS_H__ + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct _XCBKeySymbols xcb_key_symbols_t; + +xcb_key_symbols_t *xcb_key_symbols_alloc (xcb_connection_t *c); + +void xcb_key_symbols_free (xcb_key_symbols_t *syms); + +xcb_keysym_t xcb_key_symbols_get_keysym (xcb_key_symbols_t *syms, + xcb_keycode_t keycode, + int col); + +/** + * @brief Get the keycodes attached to a keysyms. + * There can be several value, so what is returned is an array of keycode + * terminated by XCB_NO_SYMBOL. You are responsible to free it. + * Be aware that this function can be slow. It will convert all + * combinations of all available keycodes to keysyms to find the ones that + * match. + * @param syms Key symbols. + * @param keysym The keysym to look for. + * @return A XCB_NO_SYMBOL terminated array of keycode, or NULL if nothing is found. + */ +xcb_keycode_t * xcb_key_symbols_get_keycode(xcb_key_symbols_t *syms, + xcb_keysym_t keysym); + +xcb_keysym_t xcb_key_press_lookup_keysym (xcb_key_symbols_t *syms, + xcb_key_press_event_t *event, + int col); + +xcb_keysym_t xcb_key_release_lookup_keysym (xcb_key_symbols_t *syms, + xcb_key_release_event_t *event, + int col); + +int xcb_refresh_keyboard_mapping (xcb_key_symbols_t *syms, + xcb_mapping_notify_event_t *event); + +/* TODO: need XLookupString equivalent */ + +/* Tests for classes of symbols */ + +int xcb_is_keypad_key (xcb_keysym_t keysym); + +int xcb_is_private_keypad_key (xcb_keysym_t keysym); + +int xcb_is_cursor_key (xcb_keysym_t keysym); + +int xcb_is_pf_key (xcb_keysym_t keysym); + +int xcb_is_function_key (xcb_keysym_t keysym); + +int xcb_is_misc_function_key (xcb_keysym_t keysym); + +int xcb_is_modifier_key (xcb_keysym_t keysym); + + +#ifdef __cplusplus +} +#endif + + +#endif /* __XCB_KEYSYMS_H__ */ diff --git a/missing b/missing new file mode 100755 index 0000000..28055d2 --- /dev/null +++ b/missing @@ -0,0 +1,376 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + tar*) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar*) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case $firstarg in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case $firstarg in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/packaging/xcb-util.spec b/packaging/xcb-util.spec new file mode 100644 index 0000000..2a8050c --- /dev/null +++ b/packaging/xcb-util.spec @@ -0,0 +1,405 @@ +Name: xcb-util +Summary: utility libraries for X C Binding +Version: 0.3.6 +Release: 0 +Group: System/Libraries +License: MIT +URL: http://xcb.freedesktop.org/ +Source0: http://xcb.freedesktop.org/dist/%{name}-%{version}.tar.gz + +BuildRequires: pkgconfig(xcb-render) +BuildRequires: pkgconfig(xcb-shm) +BuildRequires: pkgconfig(xcb) +BuildRequires: pkgconfig(xproto) +BuildRequires: gperf + + +%description +Description: %{summary} + + + +%package -n libxcb-atom +Summary: utility libraries for X C Binding -- atom +Group: System/Libraries +%description -n libxcb-atom +This package contains the library files needed to run software using +libxcb-atom, providing standard core X atom constants and atom caching. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + +%package -n libxcb-atom-devel +Summary: utility libraries for X C Binding -- atom +Group: Development/Libraries +Requires: libxcb-atom = %{version}-%{release} +Requires: pkgconfig(xcb) +%description -n libxcb-atom-devel +This package contains the header and library files needed to build software +using libxcb-atom, providing standard core X atom constants and atom caching. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + + +%package -n libxcb-aux +Summary: utility libraries for X C Binding -- aux +Group: System/Libraries +%description -n libxcb-aux +This package contains the library files needed to run software using +libxcb-aux, providing convenient access to connection setup and some +core requests. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + +%package -n libxcb-aux-devel +Summary: utility libraries for X C Binding -- aux +Group: Development/Libraries +Requires: libxcb-aux = %{version}-%{release} +Requires: pkgconfig(xcb) +%description -n libxcb-aux-devel +This package contains the header and library files needed to build software +using libxcb-aux, providing convenient access to connection setup and some +core requests. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + + +%package -n libxcb-event +Summary: utility libraries for X C Binding -- event +Group: System/Libraries +%description -n libxcb-event +This package contains the library files needed to run software using +libxcb-event, providing X callback event handling. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + +%package -n libxcb-event-devel +Summary: utility libraries for X C Binding -- event +Group: Development/Libraries +Requires: libxcb-event = %{version}-%{release} +Requires: pkgconfig(xcb) +%description -n libxcb-event-devel +This package contains the header and library files needed to build software +using libxcb-event, providing X callback event handling. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + + +%package -n libxcb-image +Summary: utility libraries for X C Binding -- image +Group: System/Libraries +%description -n libxcb-image +This package contains the library files needed to run software using +libxcb-image, providing port of Xlib's XImage and XShmImage functions. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + +%package -n libxcb-image-devel +Summary: utility libraries for X C Binding -- image +Group: Development/Libraries +Requires: libxcb-image = %{version}-%{release} +Requires: pkgconfig(xcb) +%description -n libxcb-image-devel +This package contains the header and library files needed to build software +using libxcb-image, providing port of Xlib's XImage and XShmImage functions. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + + +%package -n libxcb-keysyms +Summary: utility libraries for X C Binding -- keysyms +Group: System/Libraries +%description -n libxcb-keysyms +This package contains the library files needed to run software using +libxcb-keysyms, providing standard X key constants and conversion to/from +keycodes. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + +%package -n libxcb-keysyms-devel +Summary: utility libraries for X C Binding -- ekysyms +Group: Development/Libraries +Requires: libxcb-keysyms = %{version}-%{release} +Requires: pkgconfig(xcb) +%description -n libxcb-keysyms-devel +This package contains the header and library files needed to build software +using libxcb-keysyms, providing standard X key constants and conversion to/from +keycodes. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + + +%package -n libxcb-property +Summary: utility libraries for X C Binding -- property +Group: System/Libraries +%description -n libxcb-property +This package contains the library files needed to run software using +libxcb-property, providing callback X property-change handling. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + +%package -n libxcb-property-devel +Summary: utility libraries for X C Binding -- property +Group: Development/Libraries +Requires: libxcb-property = %{version}-%{release} +Requires: libxcb-event-devel = %{version}-%{release} +Requires: pkgconfig(xcb) +%description -n libxcb-property-devel +This package contains the header and library files needed to build software +using libxcb-property, providing callback X property-change handling. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + + +%package -n libxcb-render-util +Summary: utility libraries for X C Binding -- render-util +Group: System/Libraries +%description -n libxcb-render-util +This package contains the library files needed to run software using +libxcb-render-util, providing convenience functions for the Render extension. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + +%package -n libxcb-render-util-devel +Summary: utility libraries for X C Binding -- render-util +Group: Development/Libraries +Requires: libxcb-render-util = %{version}-%{release} +Requires: pkgconfig(xcb) +Requires: pkgconfig(xcb-render) +%description -n libxcb-render-util-devel +This package contains the header and library files needed to build software +using libxcb-render-util, providing convenience functions for the Render +extension. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + + +%package -n libxcb-reply +Summary: utility libraries for X C Binding -- reply +Group: System/Libraries +%description -n libxcb-reply +This package contains the library files needed to run software using +libxcb-reply. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + +%package -n libxcb-reply-devel +Summary: utility libraries for X C Binding -- reply +Group: Development/Libraries +Requires: libxcb-reply = %{version}-%{release} +Requires: pkgconfig(xcb) +%description -n libxcb-reply-devel +This package contains the header and library files needed to build software +using libxcb-reply. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + + +%package -n libxcb-icccm +Summary: utility libraries for X C Binding -- icccm +Group: System/Libraries +%description -n libxcb-icccm +This package contains the library files needed to run software using +libxcb-icccm, providing client and window-manager helpers for ICCCM. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + +%package -n libxcb-icccm-devel +Summary: utility libraries for X C Binding -- icccm +Group: Development/Libraries +Requires: libxcb-icccm = %{version}-%{release} +Requires: libxcb-atom-devel = %{version}-%{release} +Requires: libxcb-property-devel = %{version}-%{release} +Requires: pkgconfig(xcb) +%description -n libxcb-icccm-devel +This package contains the header and library files needed to build software +using libxcb-icccm, providing client and window-manager helpers for ICCCM. +. +The xcb-util module provides a number of libraries which sit on top of +libxcb, the core X protocol library, and some of the extension +libraries. These experimental libraries provide convenience functions +and interfaces which make the raw X protocol more usable. Some of the +libraries also provide client-side code which is not strictly part of +the X protocol but which have traditionally been provided by Xlib. + + +%prep +%setup -q -n %{name}-%{version} + + +%build + +%reconfigure --disable-static + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + + + + + + +%files -n libxcb-atom +/usr/lib/libxcb-atom.so.* + +%files -n libxcb-atom-devel +/usr/include/xcb/xcb_atom.h +/usr/lib/libxcb-atom.so +/usr/lib/pkgconfig/xcb-atom.pc + + +%files -n libxcb-aux +/usr/lib/libxcb-aux.so.* + +%files -n libxcb-aux-devel +/usr/include/xcb/xcb_aux.h +/usr/lib/libxcb-aux.so +/usr/lib/pkgconfig/xcb-aux.pc + + +%files -n libxcb-event +/usr/lib/libxcb-event.so.* + +%files -n libxcb-event-devel +/usr/include/xcb/xcb_event.h +/usr/lib/libxcb-event.so +/usr/lib/pkgconfig/xcb-event.pc + + +%files -n libxcb-icccm +/usr/lib/libxcb-icccm.so.* + +%files -n libxcb-icccm-devel +/usr/include/xcb/xcb_icccm.h +/usr/lib/libxcb-icccm.so +/usr/lib/pkgconfig/xcb-icccm.pc + +%files -n libxcb-image +/usr/lib/libxcb-image.so.* + +%files -n libxcb-image-devel +/usr/include/xcb/xcb_image.h +/usr/lib/libxcb-image.so +/usr/lib/pkgconfig/xcb-image.pc + +%files -n libxcb-keysyms +/usr/lib/libxcb-keysyms.so.* + +%files -n libxcb-keysyms-devel +/usr/include/xcb/xcb_keysyms.h +/usr/lib/libxcb-keysyms.so +/usr/lib/pkgconfig/xcb-keysyms.pc + +%files -n libxcb-property +/usr/lib/libxcb-property.so.* + +%files -n libxcb-property-devel +/usr/include/xcb/xcb_property.h +/usr/lib/libxcb-property.so +/usr/lib/pkgconfig/xcb-property.pc + +%files -n libxcb-render-util +/usr/lib/libxcb-render-util.so.* + +%files -n libxcb-render-util-devel +/usr/include/xcb/xcb_renderutil.h +/usr/lib/libxcb-render-util.so +/usr/lib/pkgconfig/xcb-renderutil.pc + +%files -n libxcb-reply +/usr/lib/libxcb-reply.so.* + +%files -n libxcb-reply-devel +/usr/include/xcb/xcb_reply.h +/usr/lib/libxcb-reply.so +/usr/lib/pkgconfig/xcb-reply.pc +%exclude /usr/include/xcb/xcb_bitops.h +%exclude /usr/include/xcb/xcb_pixel.h + diff --git a/property/Makefile.am b/property/Makefile.am new file mode 100644 index 0000000..3fb56de --- /dev/null +++ b/property/Makefile.am @@ -0,0 +1,17 @@ + +MAINTAINERCLEANFILES = Makefile.in + +lib_LTLIBRARIES = libxcb-property.la + +xcbinclude_HEADERS = xcb_property.h + +AM_CFLAGS = $(CWARNFLAGS) + +libxcb_property_la_SOURCES = property.c +libxcb_property_la_CPPFLAGS = $(XCB_CFLAGS) $(XCB_EVENT_CFLAGS) +libxcb_property_la_LIBADD = $(XCB_LIBS) $(XCB_EVENT_LIBS) +libxcb_property_la_LDFLAGS = -version-info 1:0:0 + +pkgconfig_DATA = xcb-property.pc + +EXTRA_DIST = xcb-property.pc.in diff --git a/property/property.c b/property/property.c new file mode 100644 index 0000000..161481e --- /dev/null +++ b/property/property.c @@ -0,0 +1,147 @@ +/* + * Copyright © 2008 Julien Danjou + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +#include +#include + +#include "xcb_property.h" + +xcb_get_property_cookie_t +xcb_get_any_property(xcb_connection_t *c, uint8_t del, xcb_window_t window, xcb_atom_t name, uint32_t long_len) +{ + static const xcb_atom_t type = XCB_GET_PROPERTY_TYPE_ANY; + + return xcb_get_property(c, del, window, name, type, 0, long_len); +} + +xcb_get_property_cookie_t +xcb_get_any_property_unchecked(xcb_connection_t *c, + uint8_t del, + xcb_window_t window, + xcb_atom_t name, + uint32_t long_len) +{ + return xcb_get_property_unchecked(c, del, window, name, XCB_GET_PROPERTY_TYPE_ANY, 0, long_len); +} + +static int +call_handler(xcb_connection_t *c, uint8_t state, xcb_window_t window, xcb_atom_t atom, xcb_property_handler_t *h) +{ + xcb_get_property_reply_t *propr = 0; + int ret; + + if(state != XCB_PROPERTY_DELETE) + { + xcb_get_property_cookie_t cookie = xcb_get_any_property(c, 0, window, atom, h->long_len); + propr = xcb_get_property_reply(c, cookie, 0); + } + ret = h->handler(h->data, c, state, window, atom, propr); + free(propr); + return ret; +} + +int +xcb_property_changed(xcb_property_handlers_t *prophs, uint8_t state, xcb_window_t window, xcb_atom_t atom) +{ + xcb_connection_t *c = xcb_event_get_xcb_connection(xcb_property_get_event_handlers(prophs)); + xcb_property_handler_node_t *cur; + + for(cur = prophs->head; cur; cur = cur->next) + if(cur->name == atom) + return call_handler(c, state, window, atom, &cur->h); + + if(prophs->def.handler) + return call_handler(c, state, window, atom, &prophs->def); + + return 0; +} + +static int +handle_property_notify_event(void *data, xcb_connection_t *c, xcb_property_notify_event_t *e) +{ + xcb_property_handlers_t *prophs = data; + uint8_t state = e->state; + xcb_window_t window = e->window; + xcb_atom_t atom = e->atom; + + return xcb_property_changed(prophs, state, window, atom); +} + +void +xcb_property_handlers_init(xcb_property_handlers_t *prophs, xcb_event_handlers_t *evenths) +{ + memset(prophs, 0, sizeof(prophs)); + prophs->evenths = evenths; + xcb_event_set_property_notify_handler(evenths, handle_property_notify_event, prophs); +} + +void +xcb_property_handlers_wipe(xcb_property_handlers_t *prophs) +{ + xcb_property_handler_node_t *node, *next; + + for(node = prophs->head; node; node = next) + { + next = node->next; + free(node); + } +} + +xcb_event_handlers_t * +xcb_property_get_event_handlers(xcb_property_handlers_t *prophs) +{ + return prophs->evenths; +} + +static inline void +set_prop_handler(xcb_property_handler_t *cur, uint32_t long_len, xcb_generic_property_handler_t handler, void *data) +{ + cur->long_len = long_len; + cur->handler = handler; + cur->data = data; +} + +uint8_t +xcb_property_set_handler(xcb_property_handlers_t *prophs, xcb_atom_t name, uint32_t long_len, xcb_generic_property_handler_t handler, void *data) +{ + xcb_property_handler_node_t *cur = malloc(sizeof(xcb_property_handler_node_t)); + if(!cur) + return 0; + cur->next = prophs->head; + cur->name = name; + set_prop_handler(&cur->h, long_len, handler, data); + prophs->head = cur; + return 1; +} + +uint8_t +xcb_property_set_default_handler(xcb_property_handlers_t *prophs, uint32_t long_len, xcb_generic_property_handler_t handler, void *data) +{ + set_prop_handler(&prophs->def, long_len, handler, data); + return 1; +} diff --git a/property/xcb-property.pc.in b/property/xcb-property.pc.in new file mode 100644 index 0000000..94cd0f7 --- /dev/null +++ b/property/xcb-property.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: XCB Property library +Description: XCB property convenience library +Version: @PACKAGE_VERSION@ +Requires: xcb xcb-event +Libs: -L${libdir} -lxcb-property @LIBS@ +Cflags: -I${includedir} diff --git a/property/xcb_property.h b/property/xcb_property.h new file mode 100644 index 0000000..d90f5c9 --- /dev/null +++ b/property/xcb_property.h @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2008 Julien Danjou + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +/** + * @defgroup xcb__property_t XCB Property Functions + * + * These functions ease the handling of X propertiess received. + * + * @{ + */ + +#ifndef __XCB_PROPERTY_H__ +#define __XCB_PROPERTY_H__ + +#include "xcb_event.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct xcb_property_handlers xcb_property_handlers_t; +typedef int (*xcb_generic_property_handler_t)(void *data, xcb_connection_t *c, uint8_t state, xcb_window_t window, xcb_atom_t atom, xcb_get_property_reply_t *property); + +typedef struct { + uint32_t long_len; + xcb_generic_property_handler_t handler; + void *data; +} xcb_property_handler_t; + +typedef struct xcb_property_handler_node xcb_property_handler_node_t; +struct xcb_property_handler_node { + xcb_property_handler_node_t *next; + xcb_atom_t name; + xcb_property_handler_t h; +}; + +struct xcb_property_handlers { + xcb_property_handler_node_t *head; + xcb_property_handler_t def; + xcb_event_handlers_t *evenths; +}; + +/** + * @brief Get any property from a window, from any format. + * @param c The connection to the X server. + * @param del Boolean value that determines whether the property is deleted. + * @param window The window to get property from. + * @param name The property atom name. + * @param long_len The maximum length of the property. + * @return A cookie. + */ +xcb_get_property_cookie_t xcb_get_any_property(xcb_connection_t *c, + uint8_t del, + xcb_window_t window, + xcb_atom_t name, + uint32_t long_len); + +/** + * @see xcb_get_any_property + */ +xcb_get_property_cookie_t xcb_get_any_property_unchecked(xcb_connection_t *c, + uint8_t del, + xcb_window_t window, + xcb_atom_t name, + uint32_t long_len); +/** + * @brief Initialize a property handlers structure. + * @param prophs The property handlers data structure pointer. + * @param evenths The event handlers. + */ +void xcb_property_handlers_init(xcb_property_handlers_t *prophs, xcb_event_handlers_t *evenths); + +/** + * @brief Wipe a property handler structure. + * @param prophs The property handlers data structure pointer. + */ +void xcb_property_handlers_wipe(xcb_property_handlers_t *prophs); + +/** + * @brief Get a event handlers from a property handlers data structure. + * @param prophs The property handlers. + * @return The event handlers data structure which was set if any, NULL + * otherwise. + */ +xcb_event_handlers_t *xcb_property_get_event_handlers(xcb_property_handlers_t *prophs); + +/** + * @brief Set a property handler for an event. + * @param prophs The property handlers. + * @param name The property atom name. + * @param long_len The maximum length of the property value that will be + * handled. + * @param handler The handler callback function. + * @param data Optional data that will be passed as argument of the handler + * callback function. Can be NULL safely if you do not need it. + * @return Return 1 on success, 0 otherwise. + */ +uint8_t xcb_property_set_handler(xcb_property_handlers_t *prophs, + xcb_atom_t name, + uint32_t long_len, + xcb_generic_property_handler_t handler, + void *data); + +/** + * @brief Set the default property handler. + * If a property does not have its own handler function, this one will be + * used. + * @param prophs The property handlers. + * @param name The property atom name. + * @param long_len The maximum length of the property value that will be + * handled. + * @param handler The handler callback function. + * @param data Optional data that will be passed as argument of the handler + * callback function. Can be NULL safely if you do not need it. + * @return Return 1 on success, 0 otherwise. + */ +uint8_t xcb_property_set_default_handler(xcb_property_handlers_t *prophs, uint32_t long_len, xcb_generic_property_handler_t handler, void *data); + +/** + * @brief Notify that a property has changed and call handler function callback as needed. + * @param prophs The property handlers. + * @param state The property state. + * @param window The window. + * @param atom The property atom name. + */ +int xcb_property_changed(xcb_property_handlers_t *prophs, uint8_t state, xcb_window_t window, xcb_atom_t atom); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __XCB_PROPERTY_H__ */ diff --git a/renderutil/Makefile.am b/renderutil/Makefile.am new file mode 100644 index 0000000..aaf0f48 --- /dev/null +++ b/renderutil/Makefile.am @@ -0,0 +1,14 @@ + +MAINTAINERCLEANFILES = Makefile.in + +lib_LTLIBRARIES = libxcb-render-util.la + +xcbinclude_HEADERS = xcb_renderutil.h + +libxcb_render_util_la_SOURCES = cache.c util.c glyph.c +libxcb_render_util_la_CPPFLAGS = $(XCB_CFLAGS) $(XCB_RENDER_CFLAGS) +libxcb_render_util_la_LIBADD = $(XCB_LIBS) $(XCB_RENDER_LIBS) + +pkgconfig_DATA = xcb-renderutil.pc + +EXTRA_DIST=xcb-renderutil.pc.in diff --git a/renderutil/cache.c b/renderutil/cache.c new file mode 100644 index 0000000..96acbe8 --- /dev/null +++ b/renderutil/cache.c @@ -0,0 +1,234 @@ +/* Copyright © 2006 Jamey Sharp. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or their + * institutions shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization from the authors. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "xcb_renderutil.h" +#include +#include + +typedef struct connection_cache { + struct connection_cache *next; /* keep a linked list */ + xcb_connection_t *c; /* which display this is */ + xcb_render_query_version_reply_t *version; + xcb_render_query_pict_formats_reply_t *formats; +} connection_cache; + +static struct { + pthread_mutex_t lock; + connection_cache *head; /* start of the list */ + connection_cache *cur; /* most recently used */ +} connections = { PTHREAD_MUTEX_INITIALIZER }; + +/* + * If the server is missing support for any of the required depths on + * any screen, tell the application that Render is not present. + */ + +#define DEPTH_MASK(d) (1 << ((d) - 1)) + +/* + * Render requires support for depth 1, 4, 8, 24 and 32 pixmaps + */ + +#define REQUIRED_DEPTHS (DEPTH_MASK(1) | \ + DEPTH_MASK(4) | \ + DEPTH_MASK(8) | \ + DEPTH_MASK(24) | \ + DEPTH_MASK(32)) + +/* Test each depth not explicitly advertised to see if pixmap creation + * succeeds: if it does, that depth is usable. */ +static int +pixmap_depths_usable (xcb_connection_t *c, uint32_t missing, xcb_pixmap_t pixmap, xcb_drawable_t root) +{ + xcb_void_cookie_t create_cookie[32] = { { 0 } }; + xcb_void_cookie_t free_cookie[32] = { { 0 } }; + int d; + int success = 1; + for (d = 1; d <= 32; d++) + if (missing & DEPTH_MASK(d)) + { + create_cookie[d - 1] = xcb_create_pixmap_checked (c, d, pixmap, root, 1, 1); + free_cookie[d - 1] = xcb_free_pixmap_checked (c, pixmap); + if (!create_cookie[d - 1].sequence || !free_cookie[d - 1].sequence) + { + success = 0; + break; + } + } + for (d = 0; d < 32; d++) + if (create_cookie[d].sequence || free_cookie[d].sequence) + { + xcb_generic_error_t *create_error = xcb_request_check (c, create_cookie[d]); + xcb_generic_error_t *free_error = xcb_request_check (c, free_cookie[d]); + success = success && !create_error; + free(create_error); + free(free_error); + } + return success; +} + +static int +has_required_depths (xcb_connection_t *c) +{ + xcb_screen_iterator_t screens; + xcb_pixmap_t pixmap = { -1 }; + for (screens = xcb_setup_roots_iterator(xcb_get_setup(c)); screens.rem; xcb_screen_next(&screens)) + { + xcb_depth_iterator_t depths; + uint32_t missing = REQUIRED_DEPTHS; + xcb_drawable_t root; + + for (depths = xcb_screen_allowed_depths_iterator(screens.data); depths.rem; xcb_depth_next(&depths)) + missing &= ~DEPTH_MASK(depths.data->depth); + if (!missing) + continue; + + /* + * Ok, this is ugly. It should be sufficient at this + * point to just return false, but Xinerama is broken at + * this point and only advertises depths which have an + * associated visual. Of course, the other depths still + * work, but the only way to find out is to try them. + */ + if (pixmap == -1) + pixmap = xcb_generate_id(c); + root = screens.data->root; + if (!pixmap_depths_usable (c, missing, pixmap, root)) + return 0; + } + return 1; +} + +static connection_cache * +find_or_create_display (xcb_connection_t *c) +{ + connection_cache *info; + xcb_render_query_version_cookie_t version_cookie; + xcb_render_query_pict_formats_cookie_t formats_cookie; + int present; + + /* + * look for display in list + */ + for (info = connections.head; info; info = info->next) + if (info->c == c) { + connections.cur = info; /* cache most recently used */ + return info; + } + + /* + * don't already have this display: add it. + */ + info = malloc (sizeof (connection_cache)); + if (!info) + return NULL; + info->c = c; + + version_cookie = xcb_render_query_version(c, 0, 10); + formats_cookie = xcb_render_query_pict_formats(c); + xcb_flush(c); + present = has_required_depths (c); + info->version = xcb_render_query_version_reply(c, version_cookie, 0); + info->formats = xcb_render_query_pict_formats_reply(c, formats_cookie, 0); + + if (!present || !info->version || !info->formats) + { + free(info->version); + info->version = 0; + free(info->formats); + info->formats = 0; + } + /* Check for the lack of sub-pixel data */ + else if (info->version->major_version == 0 && info->version->minor_version < 6) + info->formats->num_subpixel = 0; + + /* + * now, chain it onto the list + */ + info->next = connections.head; + connections.head = info; + connections.cur = info; + + return info; +} + +static connection_cache * +find_display (xcb_connection_t *c) +{ + connection_cache *info; + + /* + * see if this was the most recently accessed display + */ + if ((info = connections.cur) && info->c == c) + return info; + + pthread_mutex_lock(&connections.lock); + info = find_or_create_display (c); + pthread_mutex_unlock(&connections.lock); + return info; +} + +const xcb_render_query_version_reply_t * +xcb_render_util_query_version (xcb_connection_t *c) +{ + connection_cache *info = find_display (c); + if (!info) + return 0; + return info->version; +} + +const xcb_render_query_pict_formats_reply_t * +xcb_render_util_query_formats (xcb_connection_t *c) +{ + connection_cache *info = find_display (c); + if (!info) + return 0; + return info->formats; +} + +int +xcb_render_util_disconnect (xcb_connection_t *c) +{ + connection_cache **prev, *cur = NULL; + pthread_mutex_lock(&connections.lock); + for(prev = &connections.head; *prev; prev = &(*prev)->next) + if((*prev)->c == c) + { + cur = *prev; + *prev = cur->next; + if(cur == connections.cur) + connections.cur = NULL; /* flush cache */ + free(cur->version); + free(cur->formats); + free(cur); + break; + } + pthread_mutex_unlock(&connections.lock); + return cur != NULL; +} diff --git a/renderutil/glyph.c b/renderutil/glyph.c new file mode 100644 index 0000000..1721cad --- /dev/null +++ b/renderutil/glyph.c @@ -0,0 +1,287 @@ +/* Copyright © 2006 Ian Osgood + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or their + * institutions shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization from the authors. + */ + +#include +#include + +#include "xcb_renderutil.h" + +typedef struct _glyph_header_t { + uint8_t count; + uint8_t pad0[3]; + int16_t dx, dy; +} _glyph_header_t; + +/* implementation of the opaque stream */ +struct xcb_render_util_composite_text_stream_t { + /* state info */ + uint32_t glyph_size; /* 0 for unset, 1/2/4 for 8/16/32 */ + xcb_render_glyphset_t initial_glyphset; + xcb_render_glyphset_t current_glyphset; + + /* dynamically allocated stream */ + /* contents are 32-bit aligned, network byte order */ + size_t stream_len; + uint32_t *stream; + uint32_t *current; +}; + +#define CURRENT_LEN(s) (((char *)s->current - (char *)s->stream)) + +xcb_render_util_composite_text_stream_t * +xcb_render_util_composite_text_stream ( + xcb_render_glyphset_t initial_glyphset, + uint32_t total_glyphs, + uint32_t total_glyphset_changes ) +{ + xcb_render_util_composite_text_stream_t *stream; + size_t size = 32; + + /* assume worst case: each glyph has its own dx,dy */ + if (total_glyphs || total_glyphset_changes) { + size = total_glyphs * 3 * sizeof(uint32_t) + + total_glyphset_changes * 3 * sizeof(uint32_t); + } + + stream = malloc(sizeof(xcb_render_util_composite_text_stream_t)); + + stream->glyph_size = 0; + stream->initial_glyphset = initial_glyphset; + stream->current_glyphset = initial_glyphset; + + stream->stream_len = size; + stream->stream = malloc(size); + stream->current = stream->stream; + + return stream; +} + +static void +_grow_stream( xcb_render_util_composite_text_stream_t *stream, size_t increase ) +{ + size_t current_len = CURRENT_LEN(stream); + if (current_len + increase > stream->stream_len) { + uint32_t *s = realloc(stream->stream, 2 * stream->stream_len); + if (s != NULL) { + stream->stream_len *= 2; + stream->stream = s; + stream->current = stream->stream + (current_len>>2); + } + } +} + +void +xcb_render_util_glyphs_8 ( + xcb_render_util_composite_text_stream_t *stream, + int16_t dx, + int16_t dy, + uint32_t count, + const uint8_t *glyphs ) +{ + _glyph_header_t header = { count, {0,0,0}, dx, dy }; + + if (count > 252) return; /* FIXME */ + + if (stream->glyph_size != sizeof(*glyphs)) { + if (stream->glyph_size != 0) + return; + stream->glyph_size = sizeof(*glyphs); + } + _grow_stream(stream, sizeof(header) + count+3); + + memcpy(stream->current, &header, sizeof(header)); + stream->current += 2; + + memcpy(stream->current, glyphs, header.count); + stream->current += ((int)header.count+3)>>2; +} + +void +xcb_render_util_glyphs_16 ( + xcb_render_util_composite_text_stream_t *stream, + int16_t dx, + int16_t dy, + uint32_t count, + const uint16_t *glyphs ) +{ + _glyph_header_t header = { count, {0,0,0}, dx, dy }; + + if (count > 254) return; /* FIXME */ + + if (stream->glyph_size != sizeof(*glyphs)) { + if (stream->glyph_size != 0) + return; + stream->glyph_size = sizeof(*glyphs); + } + _grow_stream(stream, sizeof(header) + count*sizeof(*glyphs)+1); + + memcpy(stream->current, &header, sizeof(header)); + stream->current += 2; + + memcpy(stream->current, glyphs, header.count*sizeof(*glyphs)); + stream->current += ((int)header.count*sizeof(*glyphs)+3)>>2; +} + +void +xcb_render_util_glyphs_32 ( + xcb_render_util_composite_text_stream_t *stream, + int16_t dx, + int16_t dy, + uint32_t count, + const uint32_t *glyphs ) +{ + _glyph_header_t header = { count, {0,0,0}, dx, dy }; + + if (count > 254) return; /* FIXME */ + + if (stream->glyph_size != sizeof(*glyphs)) { + if (stream->glyph_size != 0) + return; + stream->glyph_size = sizeof(*glyphs); + } + _grow_stream(stream, sizeof(header) + count*sizeof(*glyphs)+1); + + memcpy(stream->current, &header, sizeof(header)); + stream->current += 2; + + memcpy(stream->current, glyphs, header.count*sizeof(*glyphs)); + stream->current += header.count; +} + +/* note: these glyph arrays must be swapped to network byte order */ + +void +xcb_render_util_change_glyphset ( + xcb_render_util_composite_text_stream_t *stream, + xcb_render_glyphset_t glyphset ) +{ + static _glyph_header_t header = { 255, {0,0,0}, 0, 0 }; + + if (glyphset == stream->current_glyphset) + return; + + _grow_stream(stream, 3*sizeof(uint32_t)); + + memcpy(stream->current, &header, sizeof(header)); + stream->current += 2; + + *stream->current = glyphset; + stream->current++; + + stream->current_glyphset = glyphset; +} + +typedef xcb_void_cookie_t +(*xcb_render_composite_glyphs_func) (xcb_connection_t *c, + uint8_t op, + xcb_render_picture_t src, + xcb_render_picture_t dst, + xcb_render_pictformat_t mask_format, + xcb_render_glyphset_t glyphset, + int16_t src_x, + int16_t src_y, + uint32_t glyphcmds_len, + const uint8_t *glyphcmds); + + +xcb_void_cookie_t +xcb_render_util_composite_text ( + xcb_connection_t *xc, + uint8_t op, + xcb_render_picture_t src, + xcb_render_picture_t dst, + xcb_render_pictformat_t mask_format, + int16_t src_x, + int16_t src_y, + xcb_render_util_composite_text_stream_t *stream ) +{ + xcb_render_composite_glyphs_func f; + + switch (stream->glyph_size) + { + case 1: + f = xcb_render_composite_glyphs_8; + break; + case 2: + f = xcb_render_composite_glyphs_16; + break; + case 4: + f = xcb_render_composite_glyphs_32; + break; + default: /* uninitialized */ + return xcb_no_operation(xc); + } + return f( + xc, op, src, dst, mask_format, + stream->initial_glyphset, + src_x, src_y, + CURRENT_LEN(stream), + (uint8_t *)stream->stream + ); +} + +xcb_void_cookie_t +xcb_render_util_composite_text_checked ( + xcb_connection_t *xc, + uint8_t op, + xcb_render_picture_t src, + xcb_render_picture_t dst, + xcb_render_pictformat_t mask_format, + int16_t src_x, + int16_t src_y, + xcb_render_util_composite_text_stream_t *stream ) +{ + xcb_render_composite_glyphs_func f; + + switch (stream->glyph_size) + { + case 1: + f = xcb_render_composite_glyphs_8_checked; + break; + case 2: + f = xcb_render_composite_glyphs_16_checked; + break; + case 4: + f = xcb_render_composite_glyphs_32_checked; + break; + default: /* uninitialized */ + return xcb_no_operation_checked(xc); + } + return f( + xc, op, src, dst, mask_format, + stream->initial_glyphset, + src_x, src_y, + CURRENT_LEN(stream), + (uint8_t *)stream->stream + ); +} + +void +xcb_render_util_composite_text_free ( + xcb_render_util_composite_text_stream_t *stream ) +{ + free(stream->stream); + free(stream); +} diff --git a/renderutil/util.c b/renderutil/util.c new file mode 100644 index 0000000..2d8840d --- /dev/null +++ b/renderutil/util.c @@ -0,0 +1,251 @@ +/* Copyright © 2000 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "xcb_renderutil.h" + +xcb_render_pictvisual_t * +xcb_render_util_find_visual_format (const xcb_render_query_pict_formats_reply_t *formats, + const xcb_visualid_t visual) +{ + xcb_render_pictscreen_iterator_t screens; + xcb_render_pictdepth_iterator_t depths; + xcb_render_pictvisual_iterator_t visuals; + if (!formats) + return 0; + for (screens = xcb_render_query_pict_formats_screens_iterator(formats); screens.rem; xcb_render_pictscreen_next(&screens)) + for (depths = xcb_render_pictscreen_depths_iterator(screens.data); depths.rem; xcb_render_pictdepth_next(&depths)) + for (visuals = xcb_render_pictdepth_visuals_iterator(depths.data); visuals.rem; xcb_render_pictvisual_next(&visuals)) + if (visuals.data->visual == visual) + return visuals.data; + return 0; +} + +xcb_render_pictforminfo_t * +xcb_render_util_find_format (const xcb_render_query_pict_formats_reply_t *formats, + unsigned long mask, + const xcb_render_pictforminfo_t *template, + int count) +{ + xcb_render_pictforminfo_iterator_t i; + if (!formats) + return 0; + for (i = xcb_render_query_pict_formats_formats_iterator(formats); i.rem; xcb_render_pictforminfo_next(&i)) + { + if (mask & XCB_PICT_FORMAT_ID) + if (template->id != i.data->id) + continue; + if (mask & XCB_PICT_FORMAT_TYPE) + if (template->type != i.data->type) + continue; + if (mask & XCB_PICT_FORMAT_DEPTH) + if (template->depth != i.data->depth) + continue; + if (mask & XCB_PICT_FORMAT_RED) + if (template->direct.red_shift != i.data->direct.red_shift) + continue; + if (mask & XCB_PICT_FORMAT_RED_MASK) + if (template->direct.red_mask != i.data->direct.red_mask) + continue; + if (mask & XCB_PICT_FORMAT_GREEN) + if (template->direct.green_shift != i.data->direct.green_shift) + continue; + if (mask & XCB_PICT_FORMAT_GREEN_MASK) + if (template->direct.green_mask != i.data->direct.green_mask) + continue; + if (mask & XCB_PICT_FORMAT_BLUE) + if (template->direct.blue_shift != i.data->direct.blue_shift) + continue; + if (mask & XCB_PICT_FORMAT_BLUE_MASK) + if (template->direct.blue_mask != i.data->direct.blue_mask) + continue; + if (mask & XCB_PICT_FORMAT_ALPHA) + if (template->direct.alpha_shift != i.data->direct.alpha_shift) + continue; + if (mask & XCB_PICT_FORMAT_ALPHA_MASK) + if (template->direct.alpha_mask != i.data->direct.alpha_mask) + continue; + if (mask & XCB_PICT_FORMAT_COLORMAP) + if (template->colormap != i.data->colormap) + continue; + if (count-- == 0) + return i.data; + } + return 0; +} + +xcb_render_pictforminfo_t * +xcb_render_util_find_standard_format (const xcb_render_query_pict_formats_reply_t *formats, + xcb_pict_standard_t format) +{ + static const struct { + xcb_render_pictforminfo_t templ; + unsigned long mask; + } standardFormats[] = { + /* XCB_PICT_STANDARD_ARGB_32 */ + { + { + 0, /* id */ + XCB_RENDER_PICT_TYPE_DIRECT, /* type */ + 32, /* depth */ + { 0 }, /* pad */ + { /* direct */ + 16, /* direct.red */ + 0xff, /* direct.red_mask */ + 8, /* direct.green */ + 0xff, /* direct.green_mask */ + 0, /* direct.blue */ + 0xff, /* direct.blue_mask */ + 24, /* direct.alpha */ + 0xff, /* direct.alpha_mask */ + }, + 0, /* colormap */ + }, + XCB_PICT_FORMAT_TYPE | + XCB_PICT_FORMAT_DEPTH | + XCB_PICT_FORMAT_RED | + XCB_PICT_FORMAT_RED_MASK | + XCB_PICT_FORMAT_GREEN | + XCB_PICT_FORMAT_GREEN_MASK | + XCB_PICT_FORMAT_BLUE | + XCB_PICT_FORMAT_BLUE_MASK | + XCB_PICT_FORMAT_ALPHA | + XCB_PICT_FORMAT_ALPHA_MASK, + }, + /* XCB_PICT_STANDARD_RGB_24 */ + { + { + 0, /* id */ + XCB_RENDER_PICT_TYPE_DIRECT, /* type */ + 24, /* depth */ + { 0 }, /* pad */ + { /* direct */ + 16, /* direct.red */ + 0xff, /* direct.red_MASK */ + 8, /* direct.green */ + 0xff, /* direct.green_MASK */ + 0, /* direct.blue */ + 0xff, /* direct.blue_MASK */ + 0, /* direct.alpha */ + 0x00, /* direct.alpha_MASK */ + }, + 0, /* colormap */ + }, + XCB_PICT_FORMAT_TYPE | + XCB_PICT_FORMAT_DEPTH | + XCB_PICT_FORMAT_RED | + XCB_PICT_FORMAT_RED_MASK | + XCB_PICT_FORMAT_GREEN | + XCB_PICT_FORMAT_GREEN_MASK | + XCB_PICT_FORMAT_BLUE | + XCB_PICT_FORMAT_BLUE_MASK | + XCB_PICT_FORMAT_ALPHA_MASK, + }, + /* XCB_PICT_STANDARD_A_8 */ + { + { + 0, /* id */ + XCB_RENDER_PICT_TYPE_DIRECT, /* type */ + 8, /* depth */ + { 0 }, /* pad */ + { /* direct */ + 0, /* direct.red */ + 0x00, /* direct.red_MASK */ + 0, /* direct.green */ + 0x00, /* direct.green_MASK */ + 0, /* direct.blue */ + 0x00, /* direct.blue_MASK */ + 0, /* direct.alpha */ + 0xff, /* direct.alpha_MASK */ + }, + 0, /* colormap */ + }, + XCB_PICT_FORMAT_TYPE | + XCB_PICT_FORMAT_DEPTH | + XCB_PICT_FORMAT_RED_MASK | + XCB_PICT_FORMAT_GREEN_MASK | + XCB_PICT_FORMAT_BLUE_MASK | + XCB_PICT_FORMAT_ALPHA | + XCB_PICT_FORMAT_ALPHA_MASK, + }, + /* XCB_PICT_STANDARD_A_4 */ + { + { + 0, /* id */ + XCB_RENDER_PICT_TYPE_DIRECT, /* type */ + 4, /* depth */ + { 0 }, /* pad */ + { /* direct */ + 0, /* direct.red */ + 0x00, /* direct.red_MASK */ + 0, /* direct.green */ + 0x00, /* direct.green_MASK */ + 0, /* direct.blue */ + 0x00, /* direct.blue_MASK */ + 0, /* direct.alpha */ + 0x0f, /* direct.alpha_MASK */ + }, + 0, /* colormap */ + }, + XCB_PICT_FORMAT_TYPE | + XCB_PICT_FORMAT_DEPTH | + XCB_PICT_FORMAT_RED_MASK | + XCB_PICT_FORMAT_GREEN_MASK | + XCB_PICT_FORMAT_BLUE_MASK | + XCB_PICT_FORMAT_ALPHA | + XCB_PICT_FORMAT_ALPHA_MASK, + }, + /* XCB_PICT_STANDARD_A_1 */ + { + { + 0, /* id */ + XCB_RENDER_PICT_TYPE_DIRECT, /* type */ + 1, /* depth */ + { 0 }, /* pad */ + { /* direct */ + 0, /* direct.red */ + 0x00, /* direct.red_MASK */ + 0, /* direct.green */ + 0x00, /* direct.green_MASK */ + 0, /* direct.blue */ + 0x00, /* direct.blue_MASK */ + 0, /* direct.alpha */ + 0x01, /* direct.alpha_MASK */ + }, + 0, /* colormap */ + }, + XCB_PICT_FORMAT_TYPE | + XCB_PICT_FORMAT_DEPTH | + XCB_PICT_FORMAT_RED_MASK | + XCB_PICT_FORMAT_GREEN_MASK | + XCB_PICT_FORMAT_BLUE_MASK | + XCB_PICT_FORMAT_ALPHA | + XCB_PICT_FORMAT_ALPHA_MASK, + }, + }; + + if (format < 0 || format >= sizeof(standardFormats) / sizeof(*standardFormats)) + return 0; + + return xcb_render_util_find_format (formats, + standardFormats[format].mask, + &standardFormats[format].templ, + 0); +} diff --git a/renderutil/xcb-renderutil.pc.in b/renderutil/xcb-renderutil.pc.in new file mode 100644 index 0000000..cbad815 --- /dev/null +++ b/renderutil/xcb-renderutil.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: XCB RenderUtil library +Description: XCB RENDER-extension utilities library +Version: @PACKAGE_VERSION@ +Requires: xcb xcb-render +Libs: -L${libdir} -lxcb-render-util @LIBS@ +Cflags: -I${includedir} diff --git a/renderutil/xcb_renderutil.h b/renderutil/xcb_renderutil.h new file mode 100644 index 0000000..6eb5923 --- /dev/null +++ b/renderutil/xcb_renderutil.h @@ -0,0 +1,142 @@ +/* Copyright © 2006 Jamey Sharp. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or their + * institutions shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization from the authors. + */ + +#ifndef XCB_RENDERUTIL +#define XCB_RENDERUTIL +#include + +typedef enum xcb_pict_format_t { + XCB_PICT_FORMAT_ID = (1 << 0), + XCB_PICT_FORMAT_TYPE = (1 << 1), + XCB_PICT_FORMAT_DEPTH = (1 << 2), + XCB_PICT_FORMAT_RED = (1 << 3), + XCB_PICT_FORMAT_RED_MASK = (1 << 4), + XCB_PICT_FORMAT_GREEN = (1 << 5), + XCB_PICT_FORMAT_GREEN_MASK = (1 << 6), + XCB_PICT_FORMAT_BLUE = (1 << 7), + XCB_PICT_FORMAT_BLUE_MASK = (1 << 8), + XCB_PICT_FORMAT_ALPHA = (1 << 9), + XCB_PICT_FORMAT_ALPHA_MASK = (1 << 10), + XCB_PICT_FORMAT_COLORMAP = (1 << 11) +} xcb_pict_format_t; + +typedef enum xcb_pict_standard_t { + XCB_PICT_STANDARD_ARGB_32, + XCB_PICT_STANDARD_RGB_24, + XCB_PICT_STANDARD_A_8, + XCB_PICT_STANDARD_A_4, + XCB_PICT_STANDARD_A_1 +} xcb_pict_standard_t; + + +xcb_render_pictvisual_t * +xcb_render_util_find_visual_format (const xcb_render_query_pict_formats_reply_t *formats, + const xcb_visualid_t visual); + +xcb_render_pictforminfo_t * +xcb_render_util_find_format (const xcb_render_query_pict_formats_reply_t *formats, + unsigned long mask, + const xcb_render_pictforminfo_t *template, + int count); + +xcb_render_pictforminfo_t * +xcb_render_util_find_standard_format (const xcb_render_query_pict_formats_reply_t *formats, + xcb_pict_standard_t format); + +const xcb_render_query_version_reply_t * +xcb_render_util_query_version (xcb_connection_t *c); + +const xcb_render_query_pict_formats_reply_t * +xcb_render_util_query_formats (xcb_connection_t *c); + +int +xcb_render_util_disconnect (xcb_connection_t *c); + +/* wrappers for xcb_render_composite_glyphs_8/16/32 */ + +typedef struct xcb_render_util_composite_text_stream_t xcb_render_util_composite_text_stream_t; + +xcb_render_util_composite_text_stream_t * +xcb_render_util_composite_text_stream ( + xcb_render_glyphset_t initial_glyphset, + uint32_t total_glyphs, + uint32_t total_glyphset_changes ); + +void +xcb_render_util_glyphs_8 ( + xcb_render_util_composite_text_stream_t *stream, + int16_t dx, + int16_t dy, + uint32_t count, + const uint8_t *glyphs ); + +void +xcb_render_util_glyphs_16 ( + xcb_render_util_composite_text_stream_t *stream, + int16_t dx, + int16_t dy, + uint32_t count, + const uint16_t *glyphs ); + +void +xcb_render_util_glyphs_32 ( + xcb_render_util_composite_text_stream_t *stream, + int16_t dx, + int16_t dy, + uint32_t count, + const uint32_t *glyphs ); + +void +xcb_render_util_change_glyphset ( + xcb_render_util_composite_text_stream_t *stream, + xcb_render_glyphset_t glyphset ); + +xcb_void_cookie_t +xcb_render_util_composite_text ( + xcb_connection_t *xc, + uint8_t op, + xcb_render_picture_t src, + xcb_render_picture_t dst, + xcb_render_pictformat_t mask_format, + int16_t src_x, + int16_t src_y, + xcb_render_util_composite_text_stream_t *stream ); + +xcb_void_cookie_t +xcb_render_util_composite_text_checked ( + xcb_connection_t *xc, + uint8_t op, + xcb_render_picture_t src, + xcb_render_picture_t dst, + xcb_render_pictformat_t mask_format, + int16_t src_x, + int16_t src_y, + xcb_render_util_composite_text_stream_t *stream ); + +void +xcb_render_util_composite_text_free ( + xcb_render_util_composite_text_stream_t *stream ); + +#endif /* XCB_RENDERUTIL */ diff --git a/reply/Makefile.am b/reply/Makefile.am new file mode 100644 index 0000000..aa49773 --- /dev/null +++ b/reply/Makefile.am @@ -0,0 +1,25 @@ + +MAINTAINERCLEANFILES = Makefile.in + +lib_LTLIBRARIES = libxcb-reply.la + +xcbinclude_HEADERS = xcb_reply.h + +AM_CFLAGS = $(CWARNFLAGS) + +XCB_REPLY_LIBS = libxcb-reply.la + +libxcb_reply_la_SOURCES = reply.c +libxcb_reply_la_CPPFLAGS = $(XCB_CFLAGS) +libxcb_reply_la_LIBADD = $(XCB_LIBS) -lpthread +libxcb_reply_la_LDFLAGS = -version-info 1:0:0 + +pkgconfig_DATA = xcb-reply.pc + +EXTRA_DIST=xcb-reply.pc.in + +noinst_PROGRAMS = test_reply + +test_reply_CPPFLAGS = $(XCB_CFLAGS) +test_reply_LDADD = $(XCB_LIBS) $(XCB_REPLY_LIBS) +test_reply_SOURCES = test_reply.c diff --git a/reply/reply.c b/reply/reply.c new file mode 100644 index 0000000..0cc75c6 --- /dev/null +++ b/reply/reply.c @@ -0,0 +1,146 @@ +/* + * Copyright © 2008 Julien Danjou + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +#include +#include + +#include "xcb_reply.h" + +void +xcb_reply_handlers_init(xcb_connection_t *c, xcb_reply_handlers_t *r) +{ + static const pthread_mutex_t proto_lock = PTHREAD_MUTEX_INITIALIZER; + static const pthread_cond_t proto_cond = PTHREAD_COND_INITIALIZER; + r->lock = proto_lock; + r->cond = proto_cond; + r->c = c; + r->head = NULL; +} + +xcb_connection_t * +xcb_reply_get_xcb_connection(xcb_reply_handlers_t *h) +{ + return h->c; +} + +static void +insert_handler(xcb_reply_handlers_t *h, struct xcb_reply_node *cur) +{ + struct xcb_reply_node **prev = &h->head; + while(*prev && (*prev)->request < cur->request) + prev = &(*prev)->next; + cur->next = *prev; + *prev = cur; +} + +static void +remove_handler(xcb_reply_handlers_t *h, struct xcb_reply_node *cur) +{ + struct xcb_reply_node **prev = &h->head; + while(*prev && (*prev)->request < cur->request) + prev = &(*prev)->next; + if(!(*prev) || (*prev)->request != cur->request) + return; + *prev = cur->next; + free(cur); +} + +static int +process_replies(xcb_reply_handlers_t *h, int block) +{ + int handled = 0; + pthread_mutex_lock(&h->lock); + pthread_cleanup_push((void (*)(void *)) pthread_mutex_unlock, &h->lock); + while(1) + { + struct xcb_reply_node *cur = h->head; + xcb_generic_error_t *error; + void *reply; + pthread_mutex_unlock(&h->lock); + pthread_cleanup_push((void (*)(void *)) pthread_mutex_lock, &h->lock); + if(block) + reply = xcb_wait_for_reply(h->c, cur->request, &error); + else if(!xcb_poll_for_reply(h->c, cur->request, &reply, &error)) + return handled; + if(reply || error) + { + cur->handler(cur->data, h->c, reply, error); + cur->handled = 1; + free(reply); + free(error); + } + handled |= cur->handled; + pthread_cleanup_pop(1); + if(!reply) + remove_handler(h, cur); + if(!h->head) + { + if(block) + pthread_cond_wait(&h->cond, &h->lock); + else + break; + } + } + pthread_cleanup_pop(1); + return handled; +} + +static void * +reply_thread(void *h) +{ + process_replies(h, 1); + return 0; +} + +void +xcb_reply_start_thread(xcb_reply_handlers_t *h) +{ + pthread_create(&h->thread, 0, reply_thread, h); +} + +void +xcb_reply_stop_thread(xcb_reply_handlers_t *h) +{ + pthread_cancel(h->thread); + pthread_join(h->thread, 0); +} + +void +xcb_reply_add_handler(xcb_reply_handlers_t *h, unsigned int request, xcb_generic_reply_handler_t handler, void *data) +{ + struct xcb_reply_node *cur = malloc(sizeof(struct xcb_reply_node)); + cur->request = request; + cur->handler = handler; + cur->data = data; + cur->handled = 0; + + pthread_mutex_lock(&h->lock); + insert_handler(h, cur); + pthread_cond_broadcast(&h->cond); + pthread_mutex_unlock(&h->lock); +} diff --git a/reply/test_reply.c b/reply/test_reply.c new file mode 100644 index 0000000..0805c41 --- /dev/null +++ b/reply/test_reply.c @@ -0,0 +1,86 @@ +/* + * Copyright © 2008 Ian Osgood + * Copyright © 2008 Jamey Sharp + * Copyright © 2008 Josh Triplett + * Copyright © 2008 Julien Danjou + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +#include "xcb_reply.h" + +#include +#include +#include +#include + +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; + +void fontinfo_handler(void *data, xcb_connection_t *c, xcb_generic_reply_t *rg, xcb_generic_error_t *eg) +{ + xcb_list_fonts_with_info_reply_t *rep = (xcb_list_fonts_with_info_reply_t *) rg; + if(rep) + { + int len = xcb_list_fonts_with_info_name_length(rep); + if(len) + printf("(+%u) Font \"%.*s\"\n", + (unsigned int) rep->replies_hint, + len, xcb_list_fonts_with_info_name(rep)); + else + { + pthread_mutex_lock(&lock); + pthread_cond_broadcast(&cond); + pthread_mutex_unlock(&lock); + printf("End of font list.\n"); + } + } + if(eg) + printf("Error from ListFontsWithInfo: %d\n", eg->error_code); +} + +int main(int argc, char **argv) +{ + int count = 10; + char *pattern = "*"; + xcb_connection_t *c = xcb_connect(NULL, NULL); + xcb_reply_handlers_t h; + xcb_reply_handlers_init(c, &h); + + if(argc > 1) + count = atoi(argv[1]); + if(argc > 2) + pattern = argv[2]; + + xcb_reply_add_handler(&h, xcb_list_fonts_with_info(c, count, strlen(pattern), pattern).sequence, fontinfo_handler, 0); + pthread_mutex_lock(&lock); + xcb_reply_start_thread(&h); + pthread_cond_wait(&cond, &lock); + xcb_reply_stop_thread(&h); + pthread_mutex_unlock(&lock); + + xcb_disconnect(c); + exit(0); +} diff --git a/reply/xcb-reply.pc.in b/reply/xcb-reply.pc.in new file mode 100644 index 0000000..3299a5f --- /dev/null +++ b/reply/xcb-reply.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: XCB Reply library +Description: XCB reply convenience library +Version: @PACKAGE_VERSION@ +Requires: xcb +Libs: -L${libdir} -lxcb-reply @LIBS@ +Cflags: -I${includedir} diff --git a/reply/xcb_reply.h b/reply/xcb_reply.h new file mode 100644 index 0000000..71d07ac --- /dev/null +++ b/reply/xcb_reply.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2008 Julien Danjou + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + */ + +/** + * @defgroup xcb__reply_t XCB Reply Functions + * + * These functions ease the usage of asynchronous possibility of XCB about + * the reply retrieve of sent requests. + * + * @{ + */ + +#ifndef __XCB_REPLY_H__ +#define __XCB_REPLY_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*xcb_generic_reply_handler_t)(void *data, xcb_connection_t *c, xcb_generic_reply_t *reply, xcb_generic_error_t *error); + +struct xcb_reply_node +{ + struct xcb_reply_node *next; + unsigned int request; + xcb_generic_reply_handler_t handler; + void *data; + char handled; +}; + +struct xcb_reply_handlers +{ + pthread_mutex_t lock; + pthread_cond_t cond; + struct xcb_reply_node *head; + xcb_connection_t *c; + pthread_t thread; +}; + +typedef struct xcb_reply_handlers xcb_reply_handlers_t; + +/** + * @brief Initialize a reply handlers structure. + * @param c The connection to the X server. + * @param h The reply handlers. + */ +void xcb_reply_handlers_init(xcb_connection_t *c, xcb_reply_handlers_t *h); + +/** + * @brief Get the connection to the X server used in reply handlers. + * @param h The reply handlers data structure. + * @return The connection to the X server. + */ +xcb_connection_t *xcb_reply_get_xcb_connection(xcb_reply_handlers_t *h); + +/** + * @brief Poll for reply using reply handlers. + * @param h The reply handlers data structure. + * @return The value return by the handler callback function, or 0 if no + * handler was found. + */ +int xcb_reply_poll_for_reply(xcb_reply_handlers_t *h); + +/** + * @brief Start reply handling thread. + * This thread will run forever until it is stop with xcb_reply_stop_thread. + * @param h The reply handlers. + */ +void xcb_reply_start_thread(xcb_reply_handlers_t *h); + +/** + * @brief Stop reply handling thread. + * @param h The reply handlers. + */ +void xcb_reply_stop_thread(xcb_reply_handlers_t *h); + +/** + * @brief Add a reply handler. + * @param h The reply handlers data structure to fill. + * @param request The request identifier. + * @param handler The handler to call for this request. + * @param data Optional data passed to the callback function handling request. + */ +void xcb_reply_add_handler(xcb_reply_handlers_t *h, unsigned int request, xcb_generic_reply_handler_t handler, void *data); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __XCB_REPLY_H__ */ diff --git a/xcb-util-common.h b/xcb-util-common.h new file mode 100644 index 0000000..a76fbb3 --- /dev/null +++ b/xcb-util-common.h @@ -0,0 +1,37 @@ +/* + * Common useful header for xcb-util + * + * Copyright © 2009 Julien Danjou + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or + * their institutions shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization from the authors. + * + */ + +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#define ssizeof(foo) (ssize_t)sizeof(foo) +#define countof(foo) (ssizeof(foo) / ssizeof(foo[0])) diff --git a/xcb_util_intro.in b/xcb_util_intro.in new file mode 100644 index 0000000..f063613 --- /dev/null +++ b/xcb_util_intro.in @@ -0,0 +1,24 @@ +/** +@file +@brief XCB Utility functions + +These routines are used to facilitate the use of XCB in programs. +*/ + +/** + +@mainpage XCB Utility Documentation +@version @PACKAGE_VERSION@ +@author Ian Osgood +@author Bart Massey +@author Jamey Sharp +@author Josh Triplett +@author Keith Packard +@author Vincent Torri +@author Julien Danjou +@author Arnaud Fontaine +@date 2005-2008 + +@section intro What is available ? + +*/